天天看点

Go语言开发分布式聊天室

我是一个刚学go语言的菜鸟,还没有资格谈论什么技术分享,只是为了展示fooking的实际应用,同时把我用go写的聊天室代码贴出来供大家消遣,如果有入不了各位法眼的代码,望轻喷。该聊天室基于fooking,而业务代码是采用go + fastcgi。

聊天服务器的入口main函数里有3个ip和端口配置,分别是chat服务器、router服务器和redis服务器。

chat服务器就是实现主要的聊天逻辑,router服务器是用于转发消息,redis用来存储用户信息。上面我讲过这个聊天室是基于fooking,所以客户端不是直接与go通信,而是透过fooking来访问的。我们使用go内置的fastcgi模块来创建一个服务,然后处理请求即可,这跟http服务器非常像,只是协议规范不同而已,看下面的代码就你知道创建一个fastcgi服务器有多简单了。

代码中的sessionid就是当前发送请求的客户端id,当我们要做一些uid与客户端id映射或者是要发消息给指定用户的时候就可以使用这个id。event就是当前请求的事件类型(0-表示请求,1-新连接,2-关闭连接),而聊天室只需要关心客户端请求和断开事件。请求可能是登陆、发消息或者是加入频道,而断开事件我们就需要把用户信息删除,并且把他的退出信息广播给所有在聊天室的人。代码如下:

在上面的消息处理部分,有两句rep.header().add和rep.write,这表示如果需要返回数据给当前发请求的客户端,可以添加content-length头(表示要返回给客户端的数据长度),然后调用rep.write发送数据(类似http的request对应一个response)。

代码里面的消息广播、用户分频道都是在router部分实现,他是fooking消息转发与用户数据维持的中间件。

其实开发一个聊天室可以很简单,可以直接使用websocket协议,让客户端跟服务器直接通信,简单方便,通信代价低。并且做socket服务也不受协议限制,完全可以自定义或者是使用其它轻量级的协议,比如mqtt什么的。然而为什么要使用fastcgi呢?主要是他的协议实现简单,并且扩展性也非常强,目前世界上最强大的语言php的fpm就是使用该协议与nginx进行通信,如果你的服务使用fastcgi协议开发,那么你可以完美的使用nginx与你的服务进行通信,这样做的好处是写socket服务能像写web服务一样调试,开发完一个功能你只需要简单的执行如下命令即可(当然你可能需要添加少量的代码来判断来源是从nginx还是你自己的客户端)。

网关与逻辑分离另一个好处是,当业务逻辑代码需要更新,客户端毫无察觉的,真正做到无痛更新。另外fastcgi协议本身已经支持多路复用(当然这个需要服务端的支持),这个功能可是大名鼎鼎的http到2.0才支持的哟。

文章开篇已经说了,我是一个go语言的初学者,到这里来不是为了秀go技,而是为了展示fooking与各语言的衔接。那么为什么要使用fooking?我相信很多人都知道网关这个东西(可能在游戏领域应用的更广泛一些),他其主要的目的是用于承载客户端的连接,把消息转发与业务逻辑分开,后端开发人员只需要专心写逻辑即可。这就好比我们写web的时候,从来不需要自己去实现http server。那么fooking也是这样一个开源软件,他将socket服务变的更简单。更多的特性如下:

1 动态网关添加.

2 每个客户端唯一sessionid.

3 组播(类似redis的pub/sub).

4 服务器状态监控.

5 客户端事件通知(如:新连接、关闭连接).

6 后端无语言限制(php, python, go, nodejs, etc...).

7 自定义消息协议.

8 后端长连接维持.