WebSocket能干些啥?( 二 )


2)Connection域可以认为是与Upgrade域配对的头信息 。像Nginx等代理服务器,是要先处理Connection,然后再发起协议转换的 。
3)Sec-WebSocket-Key 是随机的字符串,服务器端会用这些数据来构造出一个 SHA-1 的信息摘要 。如此操作,可以尽量避免普通 HTTP 请求被误认为 WebSocket 协议 。
其他的,像Sec-WebSocket*字样的头信息,表明了客户端支持的子协议以及其他信息 。像loT中很流行的mqtt,就可以作为WebSocket的子协议 。

WebSocket能干些啥?

文章插图
 
Python服务器端开发pip install python-socketio使用协程的方式运行 (推荐)
 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)1)事件处理方法编写事件处理方法,可以接收指定的事件消息数据,并在处理方法中对消息数据进行处理 。
@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与自定义事件处理方法的函数传入参数不同
2)发送事件消息
  • 群发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)
3)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() 
WebSocket:如何使用Nginx做WebSocket的负载均衡?nginx官网已经给出了例子 。主要是Upgrade和Connection头的设置 。
Nginx的中的配置如下:
map $http_upgrade $connection_upgrade {
default upgrade;
''close;
}
 
location /chat/{
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
需要注意的是,nginx做负载均衡,不需要配置ip_hash等参数,nginx天然支持 。由于ip_hash仅使用ip地址的前三个数字做hash,还有可能造成服务端的不均衡 。
特别注意:
在IM聊天系统场景下,Nginx提供给WebSocket的这种所谓的“负载均衡”,只能解决传统分布系统中的SLB服务器要做的事 。


推荐阅读