Giter VIP home page Giter VIP logo

link's People

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

link's Issues

执行效率和封装性的矛盾

春哥在用link重写游戏网关的时候遇到这样的问题:

网关和游戏服之间的通讯协议,是为了执行效率特别优化过的,游戏服发送给网关的消息包当中包含了要发送给客户端的完整消息包,也就是包头+包体,而不是只有包体。

在用link之前,网关是完全手工实现,没有库的依赖,所以网关读取和解析游戏服发送来的消息包之后,剩余的内容就可以直接发送给客户端,不需要做二次封包。

但是用link包的时候,由于link包没有提供直接发送完整消息包的接口,就只能把包体分离出来,然后交给link的发送接口,接着里面再重新封包。

这里就存在着封装性和执行效率的矛盾。如果link包直接提供了发送原始数据的接口给外部,那么link包的协议封装就被破坏了,细节就泄漏到了应用层。

但是如果不提供这样的接口,一些应用场景下又有局限性,无法做到最优。

大家怎么看这个问题呢?

  1. 是否应该提供发送原始数据的接口
  2. 接口以什么形式提供
  3. 是否可以做到不破坏封装

问题

1.manager为啥要加一个32的list的session啊?
2.manager和session的各种加锁操作,为啥不通过协程来规避掉, 是因为锁的效率大于协程的处理吗?

关于session的close

session close的实现是直接关闭了closeChan, 但是如果此时sendChan中还有没法送完的消息,直接close的话,会导致这些消息不会发送成功,所以这个close代表着强制关闭,如果我想要有序的关闭,应该怎么做呢?

backend_link.go

backend_link.go中的dispathMsg函数中
select default中是使用的go conn.close(true)

如果conn.recvChan被写满了堵塞了的话 后续还有消息到来 会抛出异常send on closed channel

return err

hi @idada

we must monitor return success or failed in application

// Broadcast to channel sessions.
func (channel *Channel) Broadcast(message Message) {
channel.broadcaster.Broadcast(channel, message)
}

change to

// Broadcast to channel sessions.
func (channel *Channel) Broadcast(message Message) error {
return channel.broadcaster.Broadcast(channel, message)
}

server.go

hi @idada

// Get listener address.
func (server *Server) Listener() net.Listener {
return server.listener
}
// Get packet protocol.
func (server *Server) Protocol() PacketProtocol {
return server.protocol
}

change to

// Get listener address.
func (server *Server) GetListener() net.Listener {
return server.listener
}
// Get packet protocol.
func (server *Server) GetProtocol() PacketProtocol {
return server.protocol
}

PacketN is not a good factory function name

hi @idada

func PacketN(n uint, bo binary.ByteOrder) *PNProtocol {
return &PNProtocol{
n: n,
bo: bo,
}
}

maybe NewPNProtocol is more golang style, PacketN can be a commet

func NewPNProtocol(n uint, bo binary.ByteOrder) *PNProtocol {
return &PNProtocol{
n: n,
bo: bo,
}
}

重构之后的异步发送问题

codec_async.go 文件已经不存在了,如何区分现有功能模块中的同步/异步发送?是否异步发送是只要设置Serve中的最后一个sendChanSize!=0即可?

tcp连接写,是否有必要加锁

你好,在阅读你源码的时候发现个问题想请教下,源码中session的send()方法同步情况下调用session.codec.Send(msg)加了个写锁的目的是什么?如果是为了保证写入数据包的完整性,是没有必要的,tcp底层已经有这个锁了,参见net/fd_unix.go的netFd.Write().

内置消息分发接口?

目前的接口抽象度太高,从零开始搭建一个服务端的过程不够流畅,前期准备工作太多。

对于网关和游戏这种分包 + 多消息类型的项目,都会需要重头构建一套消息识别和派发的CodecType。

是不是应该内置进消息识别和分发的接口,就可以配合fastbin或者别的协议工具快速搭建项目。

想象中应该像这样:

server, _ := link.Serve("tcp", "0.0.0.0:10010", 
    link.Packet(2, 65535, 4096, link.Uint16Handlers{
        1: PingMsgHandler,
        2: PongMsgHandler,
    }),
)

session, _ := server.Accept()

var msg link.Request

session.Receive(&msg)

msg.Process()

Performance benchmarking?

Is there a performance benchmarking for link? What is the maximized session numbers can be supported simultaneously?

It will be interesting to see some real life use cases 🍻

对 broadcast.go 的 疑问

broadcast.go

func (channel *Channel) Fetch(callback func(*Session)) {
    channel.mutex.RLock()
    defer channel.mutex.RUnlock()

    for _, sesssion := range channel.sessions {
        callback(sesssion.Session)
    }
}

callback 里面使用AsyncSend timeout 5s ,那么是不是这个广播也将 阻塞5s

packet, N

我看 N ∈ [1,2,4,8], 我觉得3也可以加上,mysql就是3

overflows int

➜  basetcpserver go run server.go 
# github.com/funny/link/codec
../../github.com/funny/link/codec/fixlen.go:57: constant 4294967295 overflows int
../../github.com/funny/link/codec/fixlen.go:58: constant 4294967295 overflows int
../../github.com/funny/link/codec/fixlen.go:60: constant 4294967295 overflows int
../../github.com/funny/link/codec/fixlen.go:61: constant 4294967295 overflows int
../../github.com/funny/link/codec/fixlen.go:137: c.fixlenReadWriter.recvBuf.Reset undefined (type bytes.Reader has no field or method Reset)

运行demo的时候报了这个错,我是新手

请问下处理性能如何?

简单的写了个server, 用link.Packet包上自己的一个CodecType, 解包有时候需要2ms, 有时候会快些400微秒

我写的codectype解包只有这样的的语句(大根10个这样的字段):
头部
binary.Read(reader, binary.BigEndian, ...)

body部分:
ReadFull

是不是我的姿势不对?

示例中的Manager同时只支持32个session吗

`func (manager *Manager) putSession(session *Session) {
smap := &manager.sessionMaps[session.id%sessionMapNum]
smap.Lock()
defer smap.Unlock()

smap.sessions[session.id] = session
manager.disposeWait.Add(1)

}`

`const sessionMapNum = 32

type Manager struct {
sessionMaps [sessionMapNum]sessionMap
disposeFlag bool
disposeOnce sync.Once
disposeWait sync.WaitGroup
}`

按照README说的 session的字面含义是会话,就是一次对话过程。每一个连接的生命周期被表达为一个会话过程,这个过程中通讯双方的消息有来有往。
意思是说同时只能有32个连接在线?

请教点问题

我非常的喜欢golang,所以想仔细认真的学习这门语言。
我准备做一个简易的规则引擎服务器小平台,就是向服务传相应的参数 可以返回数字或者是xml
一方面加深我的学习,一方面以后的工作中很可能使用到这个平台,
但是有些问题我没想明白,所以希望大神能够忙里抽闲,指点我一下,或者给我一个思路。
我打算做一个socket 服务器,这样这边的java 用socket连接 发送数据过来就直接可以得到 规则生成的数值了
连接这部分应该不算难,也没有涉及到页面,只是数据传输,所以我觉得就不必使用HTTP了
但涉及到浏览器页面对数据进行的管理的时候,我就有点想不明白了,这块应该如何 想 http协议 那样进行请求 管理数据啊?
大神有没有做过 这样的服务啊?能不能帮忙 给点建议?使用socket是不是合理啊?

link程序 , 复杂包头, 如何进行拆包?

例如包头:

typedef struct _yar_header {
    unsigned int   id;            // transaction id
    unsigned short version;       // protocl version
    unsigned int   magic_num;     // default is: 0x80DFEC60
    unsigned int   reserved;
    unsigned char  provider[32];  // reqeust from who
    unsigned char  token[32];     // request token, used for authentication
    unsigned int   body_len;      // request body len
}

消息接收、发送错位

现在github上的最新的link库 由于session中的Send、Receive去掉了lock
在codec_packet中的encodeHead和decodeHead未做lock处理 会引发消息接收、发送错位
而codec_safe只是对body进行了lock

Exit channel when session close

in the demo"\src\github.com\funny\link\examples\broadcast\main.go",line 41:
channel.Exit(session);

can this be done automatic when session is closed?
BTW,many other network framework do this internally,line socket.io in node.js

move func newSession to server.go

hi @idada
in file session.go the following codes should move to server.go , agree?

func (server *Server) newSession(id uint64, conn net.Conn) *Session {
session := NewSession(id, conn, server.protocol, server.sendChanSize, server.readBufferSize)
session.server = server
session.server.putSession(session)
return session
}

请教解码

我看了一下代码,你这个编码器的解码编码是直接挂接到Connection上的,这个时候session的Recive函数做解码处理的时候
msg, err := session.codec.Receive()
if err != nil {
session.Close()
}
这个直接从Connection中获取数据解码,你这个不处理粘包问题?始终能够保证,你这个Con读取出来的都是完整的Json包么?这个无法保证吧,而我去看了Json的,解码代码,他是读取,然后解码失败,就返回了,所以感觉,你这个地方直接绑定,对于粘包的处理,好像没做考虑?

请教一个问题,关于atomic在link中的使用

读您的代码,在很多地方看到了CAS的使用,但是我理解,在很多地方应该不会有多个线程同时访问的,比如server.go的line 89(为new session分配id),以及stop server的地方。
能否简单解释一下呢,什么情况下会多线程访问?

session.go 中的 closeChan 字段有什么用?

在整个项目中全局搜索, 发现这个字段只在 session.goClose() 函数中出现过, 而且是判断 != nil 后就关闭了. 请问这个字段具体是用来做什么的呢?

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.