Giter Club home page Giter Club logo

cellnet's People

Contributors

blade-226 avatar bwangelme avatar davyxu avatar dependabot[bot] avatar haraldnordgren avatar ironsdu avatar jeremy1108 avatar liangjiangui avatar pal301x avatar smilefisher avatar superikw avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

cellnet's Issues

【错误】lineraPipe 没有友好的退出

func (self *lineraPipe) Stop(result int) {
self.exitSignal <- result
}
func (self *lineraPipe) Wait() int {
return <-self.exitSignal
}

Stop 执行后,并没有友好地停止之前的读取 datachan 循环。

not enough arguments in call to codec.EncodeMessage

# github.com/davyxu/cellnet/proc/gorillaws \github.com\davyxu\cellnet\proc\gorillaws\transmitter.go:79:40: not enough arguments in call to codec.EncodeMessage have (interface {}) want (interface {}, cellnet.ContextSet)

websocket session.close

websocket 中调用 session.close 会引起并发写入的 panic

msg := ev.Msg.(*jsongamedef.TestEchoJsonACK)
ev.Send(&jsongamedef.TestEchoJsonACK{Content: "roger"})
ev.Ses.Close()

panic: concurrent write to websocket connection
goroutine 19 [running]:
github.com/gorilla/websocket.(*messageWriter).flushFrame(0xc042127d28, 0xc04204c501, 0xc04204c518, 0x0, 0x0, 0x0, 0x0)
github.com/davyxu/cellnet/websocket.(*wsSession).Close(0xc04210a340)

支持一下自定义listener

listener net.Listener

标准的库的net.Listener是很好,但是遇到CC攻击获取其他高并发的情况下就麻烦了
比如我想用用这个库 https://github.com/valyala/tcplisten

所以支持一下自定义Listener,

还有网络库怎么能少得了这个方便的东西:
func setMaxConn() error { var RLimit syscall.Rlimit err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &RLimit) if err != nil { return err } log.Info("get setrlimit success", zap.Uint64("cur", RLimit.Cur), zap.Uint64("max", RLimit.Max)) RLimit.Cur = 800000 RLimit.Max = 800000 err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &RLimit) if err != nil { return err } err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &RLimit) if err != nil { return err } log.Info("set setrlimit success", zap.Uint64("cur", RLimit.Cur), zap.Uint64("max", RLimit.Max)) return nil }

relay功能?

tcp 里面支持

// 带有RPC和relay功能
type MsgHooker struct {
}

请问什么是relay? 适用于怎么样的场景?

proc gorillaws接收消息崩溃

客户端发送消息包到服务器,服务器崩溃

func (WSMessageTransmitter) OnRecvMessage(ses cellnet.Session) (msg interface{}, err error) {

	conn, ok := ses.Raw().(*websocket.Conn)

	// 转换错误,或者连接已经关闭时退出
	if !ok || conn == nil {
		return nil, nil
	}

	var messageType int
	var raw []byte
	messageType, raw, err = conn.ReadMessage()

	if err != nil {
		return
	}

	switch messageType {
	case websocket.BinaryMessage:
		msgID := binary.LittleEndian.Uint16(raw)
		msgData := raw[MsgIDSize:]

		msg, _, err = codec.DecodeMessage(int(msgID), msgData)
	}

	return
}
msgID := binary.LittleEndian.Uint16(raw)

应改为

msgID := binary.LittleEndian.Uint16(raw[:MsgIDSize])

缺少peer_websocket.go

您好,克隆下来有peer_tcp.go,但找不到 peer_websocket.go,目前比较常跟client连接的是websocket
可否补上?

BroadcastToClientList 有一个小BUG

不是大问题,只是新创建空间后,地址没有赋给self对象造成的。
表现 BroadcastToClientList 指定用户不能正常收到广播。

review源码中发现问题出在:
router\routerconn.go 187行,


list = make([]int64, 0)
改成
self[routerSes] = make([]int64, 0)
list = self[routerSes]

@davyxu

websocket 客服端关闭服务端无法释放 Goroutine

我尝试建立大量链接,并关闭后,统计链接数量,一直持续增长
后来发现是github.com/davyxu/cellnet/peer/gorillaws/session.go
cleanup() 时没有清理干净导致修改后代码为
// 清理资源
func (self *wsSession) cleanup() {

self.cleanupGuard.Lock()

defer self.cleanupGuard.Unlock()

// 关闭连接
if self.conn != nil {
	self.conn.Close()
	self.conn = nil
}
   //没有清理这个
self.Close()
// 通知完成
self.exitSync.Done()

}
之后就正常,希望修复下这个问题。

这一块不是很能看懂,为什么要执行两次DecodeMessage

func (self *DecodePacketHandler) Call(ev *Event) {

	var err error
	ev.Msg, err = DecodeMessage(ev.MsgID, ev.Data)

	r := errToResult(err)
	if r != Result_OK {
		ev.Msg, _ = DecodeMessage(ev.MsgID, ev.Data)

		ev.SetResult(r)
	}

}

这一块不是很能看懂,为什么要执行两次DecodeMessage, 望解答

为啥不用io.ReadAtLeast ,这样不会粘包么

pktstream.go里
Read函数部分
直接readFull有点不靠谱吧,这样封包没发全会直接断开的吧,tcp搞的和udp一样一个包一个包发有什么特殊含义么。
主要我用websocket发送消息的时候,send我不知道是不是writeFull....内部实现又看不到。
用ReadAtLeast不就没啥问题了么。

目前master的example websocket 無作用

依照index.html發送封包
server無法解析

[DEBU] websocket_server 2018/11/15 10:17:58 session closed: 2
[DEBU] gorillawsproc 2018/11/15 10:17:58 #ws.recv(server)@3 len: 0 SessionAccepted | {}
[DEBU] websocket_server 2018/11/15 10:17:58 server accepted
[DEBU] gorillawsproc 2018/11/15 10:17:58 #ws.recv(server)@3 len: 0 |

換回8月中抓的版本可正常運行

Send的问题

const sendTotalTryCount = 100

func (self *ltvStream) Flush() error {

	var err error
	for tryTimes := 0; tryTimes < sendTotalTryCount; tryTimes++ {

		err = self.outputWriter.Flush()

		// 如果没写完, flush底层会将没发完的buff准备好, 我们只需要重新调一次flush
		if err != io.ErrShortWrite {
			break
		}
	}

	return err
}

假设要发送唯一一个非常大的包,而接收端接收非常缓慢,导致tryTimes超过sendTotalTryCount

这种情况下,是否会出现sendThtread永远阻塞在BeginPick上,而对端永远接收不到完整的包

回调地狱 Callback Hell

cellnet 是回调模式。如果用cellnet 实现逻辑服务器,一般需要访问其他服务(例如 查询好友信息, 锁服务端等) 。 这样很容易掉入Callback Hell。 请问,实际的项目中,你是如何解决这个问题的?

建议工程的描述加上 server framework关键字

因为这几天在不断搜索golang相关的游戏服务器技术,但却很难搜到cellnet,是因为一般人都是搜的 game, server framework这几个关键字。。而出来的都是些几百k的项目。 很少有人会去搜索 network library吧~ 所以只是个建议,让更多人发现cellnet.

StringHash not unique, may cause msgid same

这是测试代码
func TestStringHash(t *testing.T) {
a:="msg_protos.PKT_S2C_Reconnection_World_Status"
b:="msg_protos.ShipEquipFireReq"
t.Logf("a:%d,b:%d",StringHash(a),StringHash(b))
}
这是结果
strhash_test.go:8: a:7809,b:7809
如此下来,StringHash会有重复,会导致file.go MsgID 重复。
希望能换个MsgID的实现方式

peer mysql如何获取db连接池对象

type mysqlConnector struct {
	peer.CorePeerProperty
	peer.CoreContextSet
	peer.CoreSQLParameter

	db      *sql.DB
	dbGuard sync.RWMutex
}
func NewWrapper(drv *sql.DB) *Wrapper {

	return &Wrapper{
		drv: drv,
	}
}

db连接池对象是私有的,与数据库交互的封装需要传入连接池对象,是否应该提供接口获取连接池对象

rpc调用修改建议

当同一个消息使用rpc在不同的地方多次调用时, 会发生callback函数错乱调用,即A处的结果会调用到B处的callback函数
建议:为每一个rpc指定一个唯一的rpcid,通过rpcid找到callback函数,那么A处的结果必然调用A自己的callback函数

建议给封包那边写个文档说明

写客户端通信组件的时候也方便点不是吗。最近我在写个js和wx小程序的项目。客户端发包和解包的时候得和cellnet对应一下。我这里是写完了。但是要是有个文档我估计会更方便别人做一些后续开发。
只是提一下建议。

concurrent write to websocket connection

hi, davyxu

我在使用 cellnet 做 websocket 服务的时候,发现 event.send 会出现写并发的情况。
例如,在 websocket 例子中复制发送的内容几行:
ev.Send(&jsongamedef.TestEchoJsonACK{Content: "roger1"})
ev.Send(&jsongamedef.TestEchoJsonACK{Content: "roger2"})
ev.Send(&jsongamedef.TestEchoJsonACK{Content: "roger3"})
ev.Send(&jsongamedef.TestEchoJsonACK{Content: "roger4"})
ev.Send(&jsongamedef.TestEchoJsonACK{Content: "roger5"})
触发会报 concurrent write to websocket connection.

另外,目前 websocket 链接接收的是文本,以后会考虑加入二进制,支持 protobuf 呢?

cellnet 很棒:)

HTTP(测试中)

我看HTTP(测试中),请问一下,这个有发布计划吗?

Pick 函数的规范实现

更简洁的实现是

func (self *Pipe) Pick(retList *[]interface{}) (exit bool) {
self.listGuard.Lock()
defer self.listGuard.UnLock()

for len(self.list) == 0 {
	self.listCond.Wait()
}

// 复制出队列
   // 下面的代码保持一样的

}

封包长度有限制

@davyxu 你好,我在使用cellnet的时候,发现V5版本有默认封包长度限制,客户端发送的是完整封包(大约30K),而服务端收到的就大概只有10K左右,然后服务端就会报错,Session会断开再连接,具体错误提示如下,请问一下该如何解决?

[ERRO] tcppeer 2018/06/27 20:54:58 session closed, sesid: 2, err: msg not exists, '26479'
[DEBU] tcpproc 2018/06/27 20:54:58 #tcp.recv(server)@2 len: 0 SessionClosed | {}
[DEBU] tcpproc 2018/06/27 20:55:00 #tcp.recv(server)@3 len: 0 SessionAccepted | {}

PS:V4版本没这个问题。

问题和建议

1,问题
客户端socket 断了, 我知道是哪个socket 端了吗?
Send发消息是堵塞的吗? 如果我有几千个链接,发到后面不是要延迟好久? 然后ses 发东西的时候类似线程安全吗?
Peer 在客户端断开的时候, 发消息会宕机 , 这个还需要自己处理好多东西,
2, 建议,
感觉网络通信框架 和protobuf 还有其他的 协议要分开,没必要都支持了, 就做纯的网络框架,其他功能通过插件的方式实现
感觉golang 的特色 chan 用的很少, 总觉得不能发挥go 的优势

哈哈哈哈
很赞的设计

client构建脏包,导致server崩溃

client构建的tcp包,如果有意将ltv中的包长度小于实际长度,则server会崩溃。server在对数据copy的时候,轻信ltv注明长度,引发range溢出。

TCP 性能问题

func (self *tcpSession) sendLoop() {

tcp里面发送数据能一次多发几个包吗?游戏里面很多小包,这样服务于服务之间性能很低,日志可以在这个循环里面输出。

func WriteFull(writer io.Writer, p []byte) error {

这个没必要for ,以golang的尿性,再大的包都是一次性发送完成才返回。如果实际发送字节小于[]byte数组的长度,那基本上socket已经异常了,应该执行Close(). 发送缓冲区满了会阻塞在Write()

还有,tcp的设置一下发送和接收超时啊。这个东西没得的话,阻塞了都不知道咋回事

socket中有个错误

`连不上
if err != nil {

		if self.tryConnTimes <= reportConnectFailedLimitTimes {
			log.Errorf("#connect failed(%s) %v", self.name, err.Error())
		}

		if self.tryConnTimes == reportConnectFailedLimitTimes {
			log.Errorf("(%s) continue reconnecting, but mute log", self.name)
		}

		// 没重连就退出
		if self.autoReconnectSec == 0 {
			break
		}

		// 有重连就等待
		time.Sleep(time.Duration(self.autoReconnectSec) * time.Second)

		// 继续连接
		continue
	}`

if self.tryConnTimes <= reportConnectFailedLimitTimes应该是>=吧

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.