davyxu / cellnet Goto Github PK
View Code? Open in Web Editor NEWHigh performance, simple, extensible golang open source network library
License: MIT License
High performance, simple, extensible golang open source network library
License: MIT License
我尝试建立大量链接,并关闭后,统计链接数量,一直持续增长
后来发现是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()
}
之后就正常,希望修复下这个问题。
请问已经有了SessionXX, 为什么还要PeerXXX 事件?
如题,可否支持websocket
如题
没有英文单词 lineral
func (self *lineraPipe) Stop(result int) {
self.exitSignal <- result
}
func (self *lineraPipe) Wait() int {
return <-self.exitSignal
}
Stop 执行后,并没有友好地停止之前的读取 datachan 循环。
您好,克隆下来有peer_tcp.go,但找不到 peer_websocket.go,目前比较常跟client连接的是websocket
可否补上?
推荐用长连接还是短连接?心跳包要自己处理吗?粘包是自己处理还是框架自带?
当同一个消息使用rpc在不同的地方多次调用时, 会发生callback函数错乱调用,即A处的结果会调用到B处的callback函数
建议:为每一个rpc指定一个唯一的rpcid,通过rpcid找到callback函数,那么A处的结果必然调用A自己的callback函数
不是大问题,只是新创建空间后,地址没有赋给self对象造成的。
表现 BroadcastToClientList 指定用户不能正常收到广播。
review源码中发现问题出在:
router\routerconn.go 187行,
把
list = make([]int64, 0)
改成
self[routerSes] = make([]int64, 0)
list = self[routerSes]
写客户端通信组件的时候也方便点不是吗。最近我在写个js和wx小程序的项目。客户端发包和解包的时候得和cellnet对应一下。我这里是写完了。但是要是有个文档我估计会更方便别人做一些后续开发。
只是提一下建议。
pktstream.go里
Read函数部分
直接readFull有点不靠谱吧,这样封包没发全会直接断开的吧,tcp搞的和udp一样一个包一个包发有什么特殊含义么。
主要我用websocket发送消息的时候,send我不知道是不是writeFull....内部实现又看不到。
用ReadAtLeast不就没啥问题了么。
cellnet 是回调模式。如果用cellnet 实现逻辑服务器,一般需要访问其他服务(例如 查询好友信息, 锁服务端等) 。 这样很容易掉入Callback Hell。 请问,实际的项目中,你是如何解决这个问题的?
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, 望解答
@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版本没这个问题。
不用go的socket客户端没有例子,是不是不支持?能用纯socket给一个例子吗?
使用了一段时间 Webscoket,现在需要迁移项目到 https 下,请问 cellnet 能否支持 wss ?
tcp 里面支持
// 带有RPC和relay功能
type MsgHooker struct {
}
请问什么是relay? 适用于怎么样的场景?
这是测试代码
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的实现方式
Can the framework support two protocols(tcp & websocket) at the same time?
我看HTTP(测试中),请问一下,这个有发布计划吗?
# 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)
搞过的能不能留个游戏名,万分感谢
是否考虑支持UDP?
Line 19 in 85be6eb
标准的库的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 }
client构建的tcp包,如果有意将ltv中的包长度小于实际长度,则server会崩溃。server在对数据copy的时候,轻信ltv注明长度,引发range溢出。
依照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月中抓的版本可正常運行
如题 或者在TCPAcceptor interface里面SessionManagerSetter就是多余的。
怎么发送 []byte 数据
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 很棒:)
可以支持下websocket么,看了下这个库写的很实用。准备在当前项目里先实验用一下了。
因为这几天在不断搜索golang相关的游戏服务器技术,但却很难搜到cellnet,是因为一般人都是搜的 game, server framework这几个关键字。。而出来的都是些几百k的项目。 很少有人会去搜索 network library吧~ 所以只是个建议,让更多人发现cellnet.
可不可以给一个全局的handler注册,然后所有的msg都进这个handler,用户自己进行匹配呢?
客户端发送消息包到服务器,服务器崩溃
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])
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)
一个chat开6w个连接的话,连接server的时候正常,但是强制关闭chat 客户端的时候,服务端出现大量ESTABLISHED 连接没有关闭,也永远不会被关闭了!
`连不上
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应该是>=吧
Line 82 in 85be6eb
这里加个hook。比如一个新的连接连上来,我需要在2秒内做一个首包验证。
请问, cellnet 是否有计划,实现热更新机制。例如类似 https://github.com/facebookgo/grace
这样的实现。以个人经验,在生产环境,这个特性是非常重要的。
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上,而对端永远接收不到完整的包
对于不是golang的tcp客户端,希望给一个例子.对于初学者来得方便些.坑主说自己看协议定义可以做,但有一个例子会更好.不行用golang写一个标准的tcp;客户端也行...望采纳
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连接池对象是私有的,与数据库交互的封装需要传入连接池对象,是否应该提供接口获取连接池对象
cellnet/proc/tcp/transmitter.go
Line 57 in ebba2f2
这里的 err 忽略了,当我没有注册消息类型时,调试了蛮久。后来发现这个错误没有 log 出来
更简洁的实现是
func (self *Pipe) Pick(retList *[]interface{}) (exit bool) {
self.listGuard.Lock()
defer self.listGuard.UnLock()
for len(self.list) == 0 {
self.listCond.Wait()
}
// 复制出队列
// 下面的代码保持一样的
}
1,问题
客户端socket 断了, 我知道是哪个socket 端了吗?
Send发消息是堵塞的吗? 如果我有几千个链接,发到后面不是要延迟好久? 然后ses 发东西的时候类似线程安全吗?
Peer 在客户端断开的时候, 发消息会宕机 , 这个还需要自己处理好多东西,
2, 建议,
感觉网络通信框架 和protobuf 还有其他的 协议要分开,没必要都支持了, 就做纯的网络框架,其他功能通过插件的方式实现
感觉golang 的特色 chan 用的很少, 总觉得不能发挥go 的优势
哈哈哈哈
很赞的设计
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.