一个简单的聊天系统
代码: https://github.com/fengyh13/socket.io
1、建立长连接
客户端和服务通过websocket建立长连接,通过长连接发送消息。但是服务不可能开只一个进程,为了让客户端和每个服务进程都能建立连接,我们利用nginx的ip hash功能,使所有的客户端均匀的连接到所有的服务进程。nginx配置nginx.conf的同一个http { }如下:
upstream io_nodes {
ip_hash;
server 127.0.0.1:3003;
server 127.0.0.1:3004;
}
server {
listen 12345;
server_name localhost;
location / {
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_http_version 1.1;
proxy_pass http://io_nodes;
}
}
其中127.0.0.1:3003; 127.0.0.1:3004;是两个node.js进程。
2、RabbitMQ
可以通过mq向服务发送消息,nodejs进程从消息队列里依次取出消息处理,详细参见http://www.jianshu.com/writer?name=socket.io#/notebooks/21582589/notes/23334393
3、socket.io-redis
因为服务起了多个进程,A给B发消息时,假如:A跟node1建立长连接,B和node2建立长连接。当node1收到A发的消息时,因为A不知道B在哪里,所以就需要使用socket.io-redis进程不同实例之间通讯。如下图,node1和node2都和redis建立连接,当node1收到A的消息是,向redis服务pub(publish)一条消息,所有sub(subscribe)redis服务的node.js实例,即node1和node2都会收到该消息,node2和B建立连接,通过node.js服务全局保存的socket信息,找到node2和B建立的socket连接信息,通过该连接将消息发送给B。