最近在做一个小项目,其中一部分即时通信的功能我是通过flask-socketio来完成的后端代码编写。在尝试过程中遇到了一些问题,特在此记录,以备后用。

具体说来,想要实现的功能是这样的:每两个用户通过通过一个pair保存起来,而每个pair通过唯一的标识符加以区分;在用户连接到后端聊天服务器之后,后端通过该用户对应的pair标识符简历一个专属的聊天频道(room);这个聊天频道只有这个pair中的两个人能够进入(类似于qq私聊)。

具体实现

现在具体流程已经很清楚了,要实现的功能也比较简单,所以具体实现如下: 首先,要建立一个socketio服务器实例:

1
2
3
4
5
6
7
8
from flask_socketio import SocketIO, Namespace
from flask import Flask
def createApp():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'wtf'
    return app
app = createApp()
socketio = SocketIO(app)

现在有了这个socketio,我们就可以为他添加对应的事件:前端发来连接请求并且把该用户所属的pair标识符一并发来,我们需要接受连接请求并建立一个room,room建立之后,用户加入对应的room。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 前端请求
var chat = io.connect('ws://localhost:4000');	// 通过指定的ip和port连接后端
chat.on('connect', function(data) {
    chat.emit('message',{msg: '{{roomid}}'},function(){		//连接建立之后,向后端发送标识符
        room = io.connect('ws://localhost:4000/{{roomid}}');	//后端生成对应的room,并提供连接
        room.on('liaoxian',function(data){					//监听后端的事件
            msgPanel.append('<p>'+data+'</p><br>')
        });
        });
});
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# 后端处理
# 由于在实际运行中,可能会有大量的room需要建立,通过class将room抽象出来会更方便
class ChatRoom(Namespace):
    def on_connect(self):
        print('client connected to room')

    def on_disconnect(self):
        print('client disconnected from room')
	# 自定义的事件,前边需要加上on_
    def on_liaoxian(self, msg):
        print('running liaoxian')
        print(msg)
        self.send(msg)
    def on_recv(self, data):
        self.emit('liaoxian', data['msg'])
@socketio.on('message')
def getMsg(sss):
    print(sss)
    room = sss['msg']
    newRoom = ChatRoom('/{}'.format(room))	# 通过制定的room生成对应的聊天频道
    socketio.on_namespace(newRoom)

通过上边很简单的代码就可以完成一个简单的点到点即时通信应用,详细代码在我的github中。