一 、介绍

cellnet是一个组件化、高扩展性、高性能的开源服务器网络库

git地址:https://github.com/davyxu/cellnet

主要使用领域:

  • 游戏服务器

    方便定制私有协议,快速构建逻辑服务器、网关服务器、服务器间互联互通、对接第三方SDK、转换编码协议等

  • ARM设备

    设备间网络通讯

  • 证券软件

    内部RPC

支持多种传输协议:

  • TCP

    TCP连接器的重连,侦听器的优雅重启。

  • UDP

    纯UDP裸包收发

  • HTTP(测试中)

    侦听器的优雅重启, 支持json及form的收发及封装。编写游戏服务器时,不再需要使用第三方HTTP服务器对接SDK。

    注: 如需要对接大规模网页, 请使用第三方专业网络库,如(https://github.com/gin-gonic/gin), cellnet的http支持主要目的在用统一的地址及peer管理

  • WebSocket

    采用(github.com/gorilla/websocket)实现

支持混合消息编码:

  • cellnet内建支持以下数据编码:

    可以通过codec包自行添加新的编码格式

  • 支持混合编码收发

    无需改动代码,只需调整消息注册方式,即可达成运行期同时收发不同编码的封包

    • 与其他语言编写的服务器使用protobuf

    • 与web服务器使用json通信

    • 与Unity3D(C#)使用ProtoPlus(github.com/davyxu/protoplus)协议通信

    优点:

    • 享受不同通信协议格式的优点,避免缺点。如Protobuf适合服务器间的传输,封包小,适应面广。

    • 私有的二进制协议方便加密和客户端处理,低GC和实现复杂度。

支持多线程和单线程设计架构:

  • 单线程异步逻辑,适用于MMORPG复杂交互,免加锁处理共享数据。

  • 多线程同步逻辑,适用于机器人逻辑,每个机器人使用独立的goroutine收发处理,机器人间互不干扰。

  • 多线程并发逻辑,适用于网关,消息转发,HTTP服务器,每条消息处理都会在完全并发下。

支持远程过程调用(RPC):

  • 支持同步RPC,适用于后台服务器向其他服务器请求数据后再顺处理事务。

  • 支持异步RPC,适用于单线程服务器逻辑。

cellnet的主要流程和架构:

  • socket连接管理:cellnet网络库使用连接器和接受器(connector,acceptor)管理socket连接

  • 会话(session):客户端和服务器连接使用会话(session)处理收发包流程,收发包的流程将事件通过事件的回调(cellnet.Eventfunc)派发

  • 包处理(packet):cellent中的packet包处理会话收发流程派发的事件,实现变长封包的解析,处理和收发

  • 编码器:用户的封包使用编码器(codec)负责原始封包的字节数组和用户消息间的转换

  • 消息队列:可以将收到的消息按顺序排队并提供给用户进行处理

  • 消息元信息(messageMeta):为所有的系统提供静态的消息扩展信息,如消息的ID,编码器,创建方法等

二、客户端功能

#官方demo
package main import (
"bufio"
"github.com/davyxu/cellnet"
"github.com/davyxu/cellnet/examples/chat/proto"
"github.com/davyxu/cellnet/peer"
"github.com/davyxu/cellnet/proc"
"github.com/davyxu/golog"
"os"
"strings" _ "github.com/davyxu/cellnet/peer/tcp"
_ "github.com/davyxu/cellnet/proc/tcp"
) var log = golog.New("client") func ReadConsole(callback func(string)) { for { // 从标准输入读取字符串,以\n为分割
text, err := bufio.NewReader(os.Stdin).ReadString('\n')
if err != nil {
break
} // 去掉读入内容的空白符
text = strings.TrimSpace(text) callback(text) } } func main() { // 创建一个事件处理队列,整个客户端只有这一个队列处理事件,客户端属于单线程模型
queue := cellnet.NewEventQueue() // 创建一个tcp的连接器,名称为client,连接地址为127.0.0.1:8801,将事件投递到queue队列,单线程的处理(收发封包过程是多线程)
p := peer.NewGenericPeer("tcp.Connector", "client", "127.0.0.1:18801", queue) // 设定封包收发处理的模式为tcp的ltv(Length-Type-Value), Length为封包大小,Type为消息ID,Value为消息内容
// 并使用switch处理收到的消息
proc.BindProcessorHandler(p, "tcp.ltv", func(ev cellnet.Event) {
switch msg := ev.Message().(type) {
case *cellnet.SessionConnected:
log.Debugln("client connected")
case *cellnet.SessionClosed:
log.Debugln("client error")
case *proto.ChatACK:
log.Infof("sid%d say: %s", msg.Id, msg.Content)
}
}) // 开始发起到服务器的连接
p.Start() // 事件队列开始循环
queue.StartLoop() log.Debugln("Ready to chat!") // 阻塞的从命令行获取聊天输入
ReadConsole(func(str string) { p.(interface {
Session() cellnet.Session
}).Session().Send(&proto.ChatREQ{
Content: str,
}) }) }

三、服务端功能

#官方demo
package main import (
"github.com/davyxu/cellnet"
"github.com/davyxu/cellnet/examples/chat/proto"
"github.com/davyxu/cellnet/peer"
"github.com/davyxu/cellnet/proc"
"github.com/davyxu/golog" _ "github.com/davyxu/cellnet/peer/tcp"
_ "github.com/davyxu/cellnet/proc/tcp"
) var log = golog.New("server") func main() { // 创建一个事件处理队列,整个服务器只有这一个队列处理事件,服务器属于单线程服务器
queue := cellnet.NewEventQueue() // 创建一个tcp的侦听器,名称为server,连接地址为127.0.0.1:8801,所有连接将事件投递到queue队列,单线程的处理(收发封包过程是多线程)
p := peer.NewGenericPeer("tcp.Acceptor", "server", "127.0.0.1:18801", queue) // 设定封包收发处理的模式为tcp的ltv(Length-Type-Value), Length为封包大小,Type为消息ID,Value为消息内容
// 每一个连接收到的所有消息事件(cellnet.Event)都被派发到用户回调, 用户使用switch判断消息类型,并做出不同的处理
proc.BindProcessorHandler(p, "tcp.ltv", func(ev cellnet.Event) { switch msg := ev.Message().(type) {
// 有新的连接
case *cellnet.SessionAccepted:
log.Debugln("server accepted")
// 有连接断开
case *cellnet.SessionClosed:
log.Debugln("session closed: ", ev.Session().ID())
// 收到某个连接的ChatREQ消息
case *proto.ChatREQ: // 准备回应的消息
ack := proto.ChatACK{
Content: msg.Content, // 聊天内容
Id: ev.Session().ID(), // 使用会话ID作为发送内容的ID
} // 在Peer上查询SessionAccessor接口,并遍历Peer上的所有连接,并发送回应消息(即广播消息)
p.(cellnet.SessionAccessor).VisitSession(func(ses cellnet.Session) bool { ses.Send(&ack) return true
}) } }) // 开始侦听
p.Start() // 事件队列开始循环
queue.StartLoop() // 阻塞等待事件队列结束退出( 在另外的goroutine调用queue.StopLoop() )
queue.Wait() }

go网络库cellent实现socket聊天功能的更多相关文章

  1. Mudo C++网络库第六章学习笔记

    muduo网络库简介 高级语言(Java, Python等)的Sockects库并没有对Sockects API提供更高层的封装, 直接用它编写程序很容易掉到陷阱中: 网络库的价值还在于能方便地处理并 ...

  2. socket实现聊天功能(二)

    socket实现聊天功能(二) WebSocket协议是建立在HTTP协议之上,因此创建websocket服务时需要调用http模块的createServer方法.将生成的server作为参数传入so ...

  3. 使用NewLife网络库构建可靠的自动售货机Socket服务端(一)

    最近有个基于tcp socket 协议和设备交互需求,想到了新生命团队的各种组件,所以决定用NewLife网络库作为服务端来完成一系列的信息交互. 第一,首先说一下我们需要实现的功能需求吧 1,首先客 ...

  4. Java 网络编程 --基于UDP实现一对一聊天功能

    UDP 基本流程: UDP发送端基本流程: 1.使用DatagramSocket 指定端口 创建发送端 2.准备数据 一定转成字节数组 3. 封装成DatagramPacket 包裹,需要指定目的地 ...

  5. boost.ASIO-可能是下一代C++标准的网络库

    曾几何时,Boost中有一个Socket库,但后来没有了下文,C++社区一直在翘首盼望一个标准网络库的出现,网络上开源的网络库也有不少,例如Apache Portable Runtime就是比较著名的 ...

  6. 公布一个基于 Reactor 模式的 C++ 网络库

    公布一个基于 Reactor 模式的 C++ 网络库 陈硕 (giantchen_AT_gmail) Blog.csdn.net/Solstice 2010 Aug 30 本文主要介绍 muduo 网 ...

  7. workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的)

    workerman-chat(PHP开发的基于Websocket协议的聊天室框架)(thinkphp也是支持socket聊天的) 一.总结 1.下面链接里面还有一个来聊的php聊天室源码可以学习 2. ...

  8. 《Linux多线程服务端编程:使用muduo C++网络库》上市半年重印两次,总印数达到了9000册

    <Linux多线程服务端编程:使用muduo C++网络库>这本书自今年一月上市以来,半年之内已经重印两次(加上首印,一共是三次印刷),总印数达到了9000册,这在技术书里已经算是相当不错 ...

  9. 开源免费的C/C++网络库(c/c++ sockets library)

    (1)ACE 庞大.复杂,适合大型项目.开源.免费,不依赖第三方库,支持跨平台. http://www.cs.wustl.edu/~schmidt/ACE.html (2)Asio Asio基于Boo ...

随机推荐

  1. linux安装lolcat实现彩色文字输出信息

    [root@localhost ~]# mount /dev/sr0 /media/[root@localhost ~]# rpm -ivh epel-release-latest-7.noarch. ...

  2. d3创建多个svg元素

    当然也可以创建dom var svg = d3.select('#svg'); svg .slectAll('circle.bb')     //选中DOM中的所有circle.bb标签,当DOM中不 ...

  3. 酷狗mac版如何新建歌单?酷狗mac版收藏歌单方法

    很多朋友们都喜欢使用酷狗音乐听音乐,不过最近有使用酷狗mac音乐播放器的Mac新用户,想要新建歌单收藏歌单,但有不知道如何操作,那么苹果电脑酷狗mac版如何新建歌单收藏歌单呢?针对此问题,本文给大家介 ...

  4. Python中的网络爬虫怎么用?

    爬虫概述 (约2016年)网络爬虫个人使用和科研范畴基本不存在问题,但商业盈利范畴就要看对方了. 通过网站的Robots协议(爬虫协议)可以知道可以和不可以抓取的内容,其中User-Agent: 为允 ...

  5. canvas画布导出图片并下载

    近期在学习关于画布知识,关于 画布导出图片, 在导出jpeg格式的图片时,会发现图片背景色变成了黑色,原因是画布透明的地方 默认转成了黑色,可以在绘制画布前设置透明处背景色为白色. // 背景色转换成 ...

  6. c++ 在类函数后加const的意义

    我们定义的类的成员函数中,常常有一些成员函数不改变类的数据成员,也就是说,这些函数是"只读"函数,而有一些函数要修改类数据成员的值.如果把不改变数据成员的函数都加上const关键字 ...

  7. 使用GDI+绘制的360风格按钮控件

    将下面的代码拷贝到一个单元中,创建一个包,加入这个单元后安装.使用的时候设置好背景颜色,边框颜色,图标(png格式)相对路径的文件名称.这个控件可以利用PNG图像的颜色透明特性,背景色默认透明度为50 ...

  8. zookeeper基本概述

    zookeeper是一个分布式的协调服务框架 其本质是一个分布式的小文件存储系统,可以存储一些小的文件,官方建议每个小文件不要超过一兆 zk一般都是装奇数台,便于zk内部的一些投票选举 leader: ...

  9. bs4修改html文件和保存

    一.需求 将2个html文件保存到本地浏览器,例如: A页面(我的博客主页) B页面(爬虫四大金刚) 然后将A页面中的爬虫链接,链接的a标签中的href属性修改成本地B页面的地址,实现在本地浏览A页面 ...

  10. Python内置的一个用于命令项选项与参数解析的模块argparse

    一.argparse简单使用 我们先来看一个简单示例.主要有三个步骤: 创建 ArgumentParser() 对象 调用 add_argument() 方法添加参数 使用 parse_args() ...