Socket.IO
Socket.IO本是一个面向实时web应用的JavaScript库,现在已经成为拥有众多语言的Web即时通讯应用框架。
Socket.IO 主要使用WebSocket协议。但是如果需要的话,Socket.io可以回退到几种其它方法,例如Adobe Flash Sockets,JSONP拉取,或是传统的AJAX拉取,并且在同时提供完全相
同的接口。尽管它可以被用作WebSocket的包装库,它还是提供了许多其它功能,比如广播至多个套接字,存储与不同客户有关的数据,和异步IO操作。
Socket.IO 不等价于 WebSocket,WebSocket只是Socket.IO实现即时通讯的其中一种技术依赖,而且Socket.IO还在实现WebSocket协议时做了一些调整。
优点:
Socket.IO 会自动选择合适双向通信协议,仅仅需要程序员对套接字的概念有所了解。
有Python库的实现,可以在Python实现的Web应用中去实现IM后台服务。
缺点:
Socket.io并不是一个基本的、独立的、能够回退到其它实时协议的WebSocket库,它实际上是一个依赖于其它实时传输协议的自定义实时传输协议的实现。该协议的协商部分使得支持标 准WebSocket的客户端不能直接连接到Socket.io服务器,并且支持Socket.io的客户端也不能与非Socket.io框架的WebSocket或Comet服务器通信。因而,Socket.io要求客户端与服务器端 均须使用该框架。
我是一个python 工作者,那实际在python中怎么使用呢?
- 首先要安装 pip install python-socketio
- 创建服务器
- 方式1 使用多线程多进程模式的WSGI服务器对接(如uWSGI)
-
-
-
-
import socketio # create a Socket.IO servers sio = socketio.Server() # 打包成WSGI应用,可以使用WSGI服务器托管运行 app = socketio.WSGIApp(sio) # Flask Django
-
-
-
创建好的app对象后,使用uWSGI服务器运行此对象。
2. 方式2 作为Flask、Django应用中的一部分
-
-
-
-
from wsgi import app # a Flask, Django, etc. application import socketio # create a Socket.IO server sio = socketio.Server() app = socketio.WSGIApp(sio, app)
-
-
-
创建好App 对象,使用uWSGI服务器运行此对象。
3. 方式3 使用协程的方式运行(推荐)
-
-
-
-
import eventlet eventlet.monkey_patch() import socketio import eventlet.wsgi sio = socketio.Server(async_mode='eventlet') # 指明在evenlet模式下 app = socketio.Middleware(sio) eventlet.wsgi.server(eventlet.listen(('', 8000)), app)
-
-
-
3. 说明:
因为服务器与客户端进行即时通讯时,会尽可能的使用长连接,所以若服务器采用多进程或多线程方式运行,受限于服务器能创建的进程或者线程数,能够支持的并发连接数据端不会很高,也就是服务器性能有限。采用协程的方式运行服务器,可以提升即时通讯服务器的性能。
4 . 事件处理
不同于HTTP 服务器的编写方式,SocketIO服务器编写不再以请求Request 和响应Response来处理,而是对收发的数据以数据以消息(message)来对待,收发的不同类别消息数据又以事件来区分。
原本HTTP服务的编写中处理请求,构造响应的视图处理函数在SocketIO 服务器中修改为收发不同的事件的事件处理函数。
- 事件处理方法
- 编写时间处理方式,可以接受制定的时间消息数据,并在处理方法中对消息数据进行处理
-
@sio.on('connect') def on_connect(sid, environ): """ 与客户端建立好连接后被执行 :param sid: string sid是socketio为当前连接客户端生成的识别id :param environ: dict 在连接握手时客户端发送的握手数据(HTTP报文解析之后的字典) """ pass @sio.on('disconnect') def on_disconnect(sid): """ 与客户端断开连接后被执行 :param sid: string sid是断开连接的客户端id """ pass # 以字符串的形式表示一个自定义事件,事件的定义由前后端约定 @sio.on('my custom event') def my_custom_event(sid, data): """ 自定义事件消息的处理方法 :param sid: string sid是发送此事件消息的客户端id :param data: data是客户端发送的消息数据 """ pass
注意
-
-
connect 为特殊事件,当客户连接后自动执行
-
disconnect 为特殊事件,当客户端断开后自动执行
-
connect、disconnect 与自定义事件处理方法的函数传入参数不同
-
-
-
- 编写时间处理方式,可以接受制定的时间消息数据,并在处理方法中对消息数据进行处理
- 发送事件消息
群发
sio.emit('my event', {'data': 'foobar'})
给指定用户发
sio.emit('my event', {'data': 'foobar'}, room=user_sid)
给一组用户发
-
SocketIO提供了房间(room)来为客户端分组
-
sio.enter_room(sid, room_name)
将连接的客户端添加到一个room
@sio.on('chat') def begin_chat(sid): sio.enter_room(sid, 'chat_users')
注意:当客户端连接后,socketio会自动将客户端添加到以此客户端sid为名的room中
-
sio.leave_room(sid, room_name)
将客户端从一个room中移除
@sio.on('exit_chat') def exit_chat(sid): sio.leave_room(sid, 'chat_users')
-
sio.rooms(sid)
查询sid客户端所在的所有房间
给一组用户发送消息的示例
@sio.on('my message') def message(sid, data): sio.emit('my reply', data, room='chat_users')
也可在群组发消息时跳过指定客户端
@sio.on('my message') def message(sid, data): sio.emit('my reply', data, room='chat_users', skip_sid=sid)
-
-
使用
send
发送message
事件消息对于'message'事件,可以使用send方法
sio.send({'data': 'foobar'}) sio.send({'data': 'foobar'}, room=user_sid)
- python 客户端
-
import socketio sio = socketio.Client() @sio.on('connect') def on_connect(): pass @sio.on('event') def on_event(data): pass sio.connect('http://10.211.55.7:8000') sio.wait()
-