Ĭ��
���� �������� 7
�뿪��IM������Ʒ�¿ӣ�����3���¹����ҿ�Դ����ߣ������������·��... ��վ�����㽨��
ʹ��WebSocket��SSE����ʵ��Web����Ϣ����
΢��ɨһɨ��ע��

1��ǰ��


HTTP ����������Ҳ��Ϊ HTTP ������һ�ֿͻ���-������ͨ��ģʽ��������Ϣ�� HTTP �������첽���͵��ͻ��ˣ��������ͻ����������ڸ߶Ƚ����� Web ���ƶ�Ӧ�ó����У�һ���������ͻ�����Ҫ�������ϵشӷ�����������Ϣ�����������ͼܹ�������Ӧ�ó����ر���Ч���ڱ����У������˽� WebSocket�������ֿ������ţ�WebSocket�����̳����� �� SSE����SSE�������⣺һ��ȫ�µ�HTML5�����������¼�����������������ʵ�� HTTP ���������͵����ּ�����

�����Ƚ��������ֽ�������֮���ļ������죬�Լ������� Web �ܹ���ʵ��ÿ�ֽ����������ҽ�ͨ��һ��ʾ��Ӧ�ó���������չʾ��������һ�� SSE ʵ�֣�Ȼ������һ�����Ƶ� WebSocket ʵ�֡��������ҽ��Ƚ����ּ������������ҹ����ڲ�ͬ���� Web ���ƶ�Ӧ�ó�����ʹ�����ǵĽ��ۡ�

��ע�⣬����Ҫ����Ϥ HTTP ���������͵����Ժ͸������Ӧ�ó��������� Python ��ʹ�� CherryPy ��д�ġ�

2�������


��������������ʷ����ȫWeb�˼�ʱͨѶ����ԭ��������
��Web�˼�ʱͨѶ�����̵㣺����ѯ��Comet��Websocket��SSE��
��SSE�������⣺һ��ȫ�µ�HTML5�����������¼�������
��Comet�������⣺����HTTP�����ӵ�Web��ʵʱͨ�ż�����
�����ֿ������ţ�WebSocket�����̳���
��WebSocket���⣨һ����������ʶWebSocket������
��WebSocket���⣨����������ԭ����������ʾ��Ӧ�ð�����
��WebSocket���⣨����������WebSocketͨ��Э��ϸ����
��socket.ioʵ����Ϣ���͵�һ��ʵ����˼·��
��LinkedIn��Web�˼�ʱͨѶʵ����ʵ�ֵ�����ʮ������������
��Web�˼�ʱͨѶ�����ķ�չ��WebSocket��Socket.io�ļ���ʵ����
��Web�˼�ʱͨѶ��ȫ����վ��WebSocket�ٳ�©������(��ʾ������)��
����Դ����Pomeloʵ�����Web�˸����ֲܷ�ʽIM������������
>> ����ͬ������ ����

3����ͳ������-��Ӧ��ģʽ�ľ�����


�����ϵĿͻ���-������ͨ���ڹ�ȥ����һ������-��Ӧģ�ͣ�Ҫ���ͻ��ˣ����� Web ����������������������Դ��������ͨ����������������Դ����Ӧ�ͻ���������������Դ�����ã����߿ͻ���û��Ȩ�޷���������ô�������ᷢ��һ��������Ϣ��������-��Ӧ�ܹ��У����������������ͻ��˷���δ����������Ϣ��

���� Web Ӧ�ó������ø�ǿ���͸��߽����ԣ�����-��Ӧģ�͵ľ�����Ҳ��ʼ���ֳ�������Ҫ��Ƶ�����µĿͻ���Ӧ�ó�����Ҫ����Ƶ���ط��� GET ���������ּ�����Ϊ��ѯ���ڸ߷��ڼ䣬�����ܻ�ʹ�����������ظ����������������⡣�ü���Ч�ʵ��£���Ϊ�ͻ��˷��͵�����������û�з��ظ��¡����⣬�ͻ���ֻ�ܰ�ָ������������ѯ�������ܼ����ͻ��˵���Ӧ�ٶȡ�

HTTP ���������ͼ����ij��֣�����Ϊ�˽�����Ƶ����ѯ���ص������������������ޡ������Ƕ��ڽ���ʽ Web Ӧ�ó��򣬱�����Ϸ����Ļ����������Web �������ܸ���Ч���������ݿ���ʱ���ͻ��˷��͸��¡�

���ڡ�����-��Ӧ��ģʽ����ϸԭ�������μ���������������ʷ����ȫWeb�˼�ʱͨѶ����ԭ����������

4���Ƚ� WebSocket �� SSE


1��������


WebSocket �� SSE ���Ǵ�ͳ����-��Ӧ Web �ܹ������������������Dz�����ȫ��ͻ�ļ�����WebSocket �ܹ��ڿͻ�����������֮������һ���׽��֣�����ʵ��ȫ˫����˫����ͨ�š����跢�� GET ��Ϣ���ȴ���������Ӧ���ͻ���ֻ���������׽��֣����շ��������£���ʹ���յ���������������֧�ָ��ֽ������ͻ���Ҳ����ʹ���׽�����������ͨ�ţ������ڳɹ��յ�����ʱ���� ACK ��Ϣ��

SSE ��һ�ָ��򵥵ı�׼������Ϊ HTML5 ����չ�������ġ����� SSE ֧�ִӷ��������ͻ��˷����첽��Ϣ�����ͻ����޷���������������Ϣ�����ڿͻ���ֻ�����մӷ����������ĸ��µ�Ӧ�ó�����SSE �İ�˫��ͨ��ģ�����ʺϡ��� WebSocket ���ȣ�SSE ��һ�����������ǻ��� HTTP �����еģ�����Ҫ����������

������Ҫ�ڿͻ�����������֮��Ƶ��ͨ�ŵĶ���; Web Ӧ�ó�������ȻӦ��ѡ�� WebSocket������ϣ���ӷ��������ͻ��˴����첽���ݣ�������Ҫ��Ӧ��Ӧ�ó�����SSE ���ʺ�һЩ��

2������֧��


�ڱȽ� HTTP Э��ʱ��������֧����һ����Ҫ�Ŀ������ء������� 1 �е����ݣ����Կ��������ִ���������֧�� WebSocket Э�飬�����ƶ���������Microsoft IE �� Edge ��֧�� SSE��

�� 1. 2017 �� 1 ��������ʹ�÷ֲ���
ʹ��WebSocket��SSE����ʵ��Web����Ϣ����_111.png

���ڱ��������������������е�Ӧ�ó�����WebSocket Ŀǰ�Ǹ��õ�ѡ����

3����������


�ڱȽ�Э��ʱ�������� WebSocket �� SSE �Ƚ��µ�Э�飬��������Ҫ���ǵ���һ�����ء������� ���������� ָ���Ǵ����У�������Ҫ������ʱ��Ϊʹ�ø���Э����Ӧ�ó�����д���롣���ھ����ϸ���ʱ�����ƻ򿪷�Ԥ������Ŀ������ָ���ر���Ҫ��

ʵ�� SSE �Ĺ������� WebSocket Ҫ�ٵöࡣ���ʺ��κ�ʹ�� HTML5 ��д��Ӧ�ó�������Ҫ�����ڴӷ��������͵��ͻ��˵���Ϣ������һ�� HTTP ��ͷ��������������ȷ��ͷ���ͻ��˾ͻ��Զ�����Ϣʶ��Ϊ���������͵��¼�����ͬ�� WebSocket��SSE ����Ҫ�ڷ��������ͻ���֮�佨����ά���׽������ӡ�

WebSocket Э��Ҫ������һ�����������׽����������ͻ������ӡ��ͻ����Զ�����һ�������������׽��ֲ��ȴ���Ϣ����Ϣ�����첽���͡�ÿ��Ӧ�ó��򶼿��Զ����Լ�����Ϣ��ʽ���־����ӣ������źţ����Եȡ��� 2 �ܽ��� SSE �� WebSocket Э�������ӡ�

�� 2. �Ƚ� SSE �� WebSocket��
ʹ��WebSocket��SSE����ʵ��Web����Ϣ����_222.png

����������ͨ��һ���򵥵� Web Ӧ�ó���ʾ�����˽�ÿ�ּ����Ĺ���ԭ����

5������ SSE Ӧ�ó���


SSE ��һ�ֽ�ʹ�� HTTP �����첽��Ϣ�� HTML5 ��׼����ͬ�� WebSocket��SSE ����Ҫ�ں��˴����������׽��֣�Ҳ����Ҫ��ǰ�˴������ӡ������󽵵��˸����ԡ�

1SSE ǰ��


�嵥 1 ������һ��ʹ�� SSE �ļ��� HTTP ����������Ӧ�ó����� UI ���룺
var source = new EventSource(��/user-log-stream��);
source.onmessage = function(event) {
var message = event.data; 
// do stuff based on received message 
};

EventSource ��һ�������������� HTTP ���ӵĽӿڡ�������ʹ���¼�����ʽ ����Ϣ���͵��ͻ��ˣ����ָ�ʽ��һ��ʹ�� UTF-8 �����ļ򵥵��ı���������������ϵ����HTTP ���ӻ��Ը�����Ϣ�����ֿ��ţ��Ա��������ܷ��͸��¡����嵥 1 �У����Ǵ�����һ�� HTTP ������������ /#tabs/user-log-stream URI ���ص��¼���

2SSE ����


�ں��ˣ�����Ϊ URL /user-log-stream ������һ�����������÷���������ǰ�˽����������󣬲�����һ���첽��Ϣ������ͨ�š�SSE �ͻ��˲�����������������Ϣ��
�嵥 2 �еĴ�����ʾ�˺��˴��롣

�嵥 2. SSE ���ˣ�
import cherrypy
  
class UserLogStream
    messages = []
  
    @cherrypy.expose
    def stream(self):
        cherrypy.response.headers["Content-Type"] = "text/event-stream"
        while True:
            if len(messages) > 0:
                for msg in messages:
                    data = ��data:�� + msg + ��\n\n��
                    yield data
                 messages = []
  
routes_dispatcher = cherrypy.dispatch.RoutesDispatcher()
routes_dispatcher.connect(��user-log-stream��, ��/��, controller = UserLogStream(), action=��stream��)

UserLogStream ���� stream ������������ÿ���� /user-log-stream URI ���ӵ� EventSource���κδ�������Ϣ���������͵������ӵ� EventSource����ע�⣬��Ϣ��ʽ���ǿ�ѡ�ģ�SSE Э��Ҫ����Ϣ�� data: ��ͷ���� \n\n ��β��������Щʾ����ʹ���� HTTP ��Ϊ��Ϣ��ʽ����Ҳ����ʹ�� JSON ����һ�ָ�ʽ������Ϣ��

��������һ���dz������� SSE ʵ��ʾ����������ʾ�˸�Э���ļ����ԡ�

6������ WebSocket Ӧ�ó���


�� SSE ʾ��һ����WebSocket Ӧ�ó������� CherryPy��һ�� Python Web ���ܣ���������Project WoK �Ǻ��� Web ��������python-websockify �����������׽������ӡ��ò����� Kimchi ��һ���֡�

����������

  • Project WoK������ Python �߼����ṩҪ�����ͷ������㲥����Ϣ��
  • Websockify �������˴����� python-websockify ��ʵ�֣���ʹ�� Unix �׽��ִ����ͷ�����������Ϣ��������Щ��Ϣ���͵� UI �����ӵ� WebSocket��
  • ���ͷ�������һ����ͨ Unix �׽��ַ����������������ӵĿͻ��˹㲥������Ϣ��
  • ǰ�ˣ�UI �� Websockify �������� WebSocket ���ӣ���������������Ϣ�����ݾ�������Ϣ������ִ��һ���ض�����������ˢ��һ���б������û���ʾһ����Ϣ��

1Websockify ����


Websockify ������ python-websockify ��ʵ�֡���ʹ�� CherryPy Web ������������ʵ�ֳ�ʼ�������嵥 3 ��ʾ��

�嵥 3. Websockify ������
params = {'listen_host': '127.0.0.1',
          'listen_port': config.get('server', 'websockets_port'),
          'ssl_only': False}
  
# old websockify: do not use TokenFile
if not tokenFile:
    params['target_cfg'] = WS_TOKENS_DIR
  
# websockify 0.7 and higher: use TokenFile
else:
    params['token_plugin'] = TokenFile(src=WS_TOKENS_DIR)
  
def start_proxy():
    try:
        server = WebSocketProxy(RequestHandlerClass=CustomHandler,
                                **params)
    except TypeError:
        server = CustomHandler(**params)
  
    server.start_server()
  
proc = Process(target=start_proxy)
proc.start()
return proc

Websockify ������������ע�������ƶ��󶨵����� WebSocket URI��������ʾ��

�嵥 4. ������ע�������ƣ�
def add_proxy_token(name, port, is_unix_socket=False):
    with open(os.path.join(WS_TOKENS_DIR, name), 'w') as f:
        """
        From python documentation base64.urlsafe_b64encode(s)
        substitutes - instead of + and _ instead of / in the
        standard Base64 alphabet, BUT the result can still
        contain = which is not safe in a URL query component.
        So remove it when needed as base64 can work well without it.
        """
        name = base64.urlsafe_b64encode(name).rstrip('=')
        if is_unix_socket:
            f.write('%s: unix_socket:%s' % (name.encode('utf-8'), port))
        else:
            f.write('%s: localhost:%s' % (name.encode('utf-8'), port))

����������һ����Ϊ myUnixSocket �� Websockify ������Ŀ�����

����Ŀͨ�������� WebSocket ���Ӵ��͵� Unix �׽��� /run/my_socket��
add_proxy_token(��myUnixSocket��, ��/run/my_socket��, True)

�� UI �У�����ʹ������ URI ����һ���� Unix �׽��ֵ� WebSocket ���ӣ�
wss://<server_address>:<port>/websockify?token=<b64encodedtoken>

�� URI �У�b64encodedtoken �� myUnixSocket �ַ����� base64 ֵ�������� = �ַ����йش����õĸ�����Ϣ��������WebSocket ����ģ����

2���ͷ�����


���ͷ�����������Ҫ����

  • ��������ͬʱ�����������ӣ�
  • �������������������ӵĿͻ��˹㲥ͬһ����Ϣ��

���ڴ�ʾ������;�����ͷ��������䵱һ���㲥�����������ܹ��������Կͻ��˵���Ϣ�������Dz�ϣ����������

�嵥 5 ���������ͷ������ij�ʼ�������� Python ���롣���ɷ��� GitHub �ϵ� Project WoK ����ȡ pushserver ģ�������հ汾����

�嵥 5. WebSocket ���ͷ�������
class PushServer(object):
  
    def __init__(self):
        self.set_socket_file()
  
        websocket.add_proxy_token(TOKEN_NAME, self.server_addr, True)
  
        self.connections = []
  
        self.server_running = True
        self.server_socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.server_socket.setsockopt(socket.SOL_SOCKET,
                                      socket.SO_REUSEADDR, 1)
        self.server_socket.bind(self.server_addr)
        self.server_socket.listen(10)
        wok_log.info('Push server created on address %s' % self.server_addr)
  
        self.connections.append(self.server_socket)
        cherrypy.engine.subscribe('stop', self.close_server, 1)
  
        server_loop = threading.Thread(target=self.listen)
        server_loop.setDaemon(True)
        server_loop.start()
  
  
    def listen(self):
        try:
            while self.server_running:
                read_ready, _, _ = select.select(self.connections,
                                                 [], [], 1)
                for sock in read_ready:
                    if not self.server_running:
                        break
  
                    if sock == self.server_socket:
  
                        new_socket, addr = self.server_socket.accept()
                        self.connections.append(new_socket)
                    else:
                        try:
                            data = sock.recv(4096)
                        except:
                            try:
                                self.connections.remove(sock)
                            except ValueError:
                                pass
  
        except Exception as e:
            raise RuntimeError('Exception occurred in listen() of pushserver '
                               'module: %s' % e.message)
  
  
    def send_notification(self, message):
        for sock in self.connections:
            if sock != self.server_socket:
                    sock.send(message)

PushServer() ���� __init__() ������ʼ�� Unix �׽��֣��Ա��������ӡ������� WebSocket ������Ҳ������һ�����ơ������ƽ���ǰ������ WebSocket ���ӵ� URI �С�

��ͨ�����෽��ʵ�ַ��������ͼܹ������ڹ㲥����������ʵ�ֵ���;������Ϊʹ��һ���������߳� (select.select()) ��������֪���������򵥵ķ����������listen() ������һ���ػ��߳������У����������������ӡ�select.select �����Է�������������ʽ���У��������� self.connections �����������׽��ֶ�׼���ö�ȡʱ���أ�������һ�볬ʱ�󷵻ء����������Ӻ������ᱻ���ӵ� self.connections �����С����ӹر�ʱ������������ɾ������

listen() ������ͨ�����ַ�����������ɾ���׽��֣��� recv() ���õ� except �������м��⵽�׽����ѹرգ������յ�һ�� CLOSE ��Ϣ��send_notification() ������������Ϣ�㲥�����������ǵĿͻ��ˡ��ڿͻ���ȡ������ʱ������ʹ���� except �������ر��׽������ӡ����ܵ���ʹ�� listen() �رտͻ�����������֮�����׽������ӣ���Ϊ���������ܵ��� send_notification() �����з����ܵ��𻵴�����

��һ�ڽ�����ϸ�ؽ�����һ�㡣

7���ų� WebSocket ǰ�˵Ĺ���


�������ú��������ԱȽ����ף�����дǰ�˴�����û����ô�����ˡ��Ӿ����򿪻��ǹر����������ӵ�����ijЩ API �ķ�ʽ�ϵIJ��죬WebSocket ǰ�˴�����������ս���ڽ�����Щ��սʱ����Ҫ�������ú��˴�����ijЩԪ�ء�

��һ��������Ϊ���� UI ά������ WebSocket ���ӣ��������ö��������򿪵� WebSocket ���ӡ����ǿ��ܻ��ȿ��Ƕ������� WebSocket ���ӡ�������Ϊ������ UI �����Ӻ����յ�һ���ض���Ϣʱ��Ӧ����һ������ �� �����ȴ�ij���������ɡ����������յ��첽��Ϣ��������Ҫ�������ӡ������� UI �ͺ��˽�ԼһЩ��Դ������������Ҫ����ÿ���Ѵ򿪵� WebSocket ���������ڡ�

���������ӷ������յ������첽��Ϣ�� UI�������־� WebSocket ���ӿ��ܸ����ʡ������־����ӱ�����֪ͨ���������κ����� UI ���������յ�����Ϣ��ִ�����ز�����

ÿ��������������������֮�أ����潫����ÿ������������ʹ�����ʺ�����Ӧ�ó����ķ�������Ҫ��

1���� WebSocket ����


Ҫ�򿪺͹ر� WebSocket��ֻ������һ�����캯�����򿪺͵��� close() ���������ǣ�����ҳ��ˢ��֮������������Ϊ�ϵIJ����������������úܸ��ӡ�ÿ�δ��� WebSocket ������ WebSocket ��������һ�����ӣ�Ȼ�������˵�ʵ�����ͷ������������ӡ��������ڹر�֮ǰ�ᱣ�ִ򿪡��������´��롣

�嵥 6. ��ÿ���յ�����Ϣ�ϵ��� refreshInterface()��
notificationsWebSocket = new WebSocket(url, ['base64']);
notificationsWebSocket.onmessage = function(event) {
    refreshInterface();
};

���嵥 6 �У�onmessage ��һ���¼�����������ÿ�����׽������յ�һ������Ϣʱ������������refreshInterface() ��������Ϣ����ʱ�����á������򿪶��� notificationsWebSocket �������������� refreshInterface() ���Ρ�

��ǰ�˺ͺ��˶��ԣ��򿪱�������Ҫ�ĸ����� WebSocket ������Ȼ��һ����Դ�˷ѡ��⻹���������벻���ķ��ա�Ϊ�˽�����Щ���⣬���ǿ��Ա����򿪲���Ҫ�� WebSocket ���ӣ����ڲ�����Ҫ��������ʱ�ر����ǡ������ֶ���ͨ���������ر� WebSocket���������ڲ��Ե��������У�������������ˢ�»��ر�ʱ��������������ʱ��Chrome �� Firefox �����ر��Ѵ򿪵� WebSocket ���ӡ�

WebSocket �ر�ʱ���ᷢ�������£�

  • ����һ����Ϊ onclose ���¼�����������ִ���κθ���������
  • �պ϶ˣ��ڱ�����Ϊ UI WebSocket������һ�ιر�������������һ�ˡ��ڴ˹����У��ᷢ��һ��ֵΪ 0x8 �Ĺر�֡�� close frame�����յ���֡ʱ�����˻�ֹͣ�������ݲ������ر������ڵ��׽��ֶˡ����� onclose ���������������˺����������ͣ��˹��̶��ᷢ����

���������£������� onclose �����������������ͷ��������յ��ر�֡���ź����ǣ����ڲ��Դ˽׶ε�ʵ��ʱ�����Ĺ��̲��������ġ�

2Websockify �����͹ر�֡


������д����ʱ��Websockify �������� (v0.8.0-2) ���Ὣ�ر�֡ת���� Unix �׽��֣��̶�ת�������ͷ����������ˣ�UI �׽����е����ӿ����ѹرգ������ͷ���������֪�飬��ʹ�����ڵ����Ӷ˱��ִ򿪡�
���ͷ��������Խ�һ������Ϣ�㲥���������ӣ������ѹرյ��׽��֣�ʱ�������յ��ܵ����𻵵Ĵ���������δ��ȷ�����������ܵ������ͷ���������ֹ���С����������׽��ַ�����һ�� send_notification ��Ϣ��

�嵥 7. send_notification ���¹ܵ��𻵴�����
def send_notification(self, message):
    for sock in self.connections:
        if sock != self.server_socket:
                sock.send(message)

��������������һ�������ǽ� sock.send() ���ð�װ��һ�� try/except �У�Ȼ�������ܵ������쳣��һ�����������ǽ���һ�ζ��صĹر����֣�ʹ�� onclose �¼��������������˷���������һ����Ϣ�����ͷ�������Ȼ���ر����Լ����׽������ӣ����� send_notification �������䡣

���������ǽ����Ըý���������

3ʹ�� onclose ���͹ر���Ϣ


onclose �¼���������������ֹ WebSocket ����֮ǰ�����á����˿�������Ȼ��Ч�����ǵ��뷨�������ɾ��عر����ӣ������������ͷ���������һ���ر���Ϣ������֪���׽��ֽ���ǰ�˹رա������Ͻ�������ģ�����ǹر�֡�ڹر������еĽ�ɫ��

���嵥 8 �У�WebSocket �ڹر�����ǰ�����ͷ���������һ�� CLOSE ��Ϣ��

�嵥 8. �� onclose �¼��з��� CLOSE ��Ϣ��
notificationsWebSocket = new WebSocket(url, ['base64']);
(...)
notificationsWebSocket.onclose = function() {
    notificationsWebSocket.send(window.btoa(��CLOSE��));
};

�����ͷ������У����Ǽ����� UI ������������Ϣ���鿴�Ƿ��յ��� CLOSE ��Ϣ�������յ�����Ϣ���������ر��׽��֣�������ʾ��

�嵥 9. ���ͷ������� CLOSE ����Ӧ��
def listen(self):
    try:
        while self.server_running:
            read_ready, _, _ = select.select(self.connections,
                                             [], [], 1)
            for sock in read_ready:
                if not self.server_running:
                    break
  
                if sock == self.server_socket:
  
                    new_socket, addr = self.server_socket.accept()
                    self.connections.append(new_socket)
                else:
                    try:
                        data = sock.recv(4096)
                    except:
                        try:
                            self.connections.remove(sock)
                        except ValueError:
                            pass
  
                        continue
                    if data and data == 'CLOSE':
                        try:
                            self.connections.remove(sock)
                        except ValueError:
                            pass
                        sock.close()

�� WebSocket �رպͷ��� CLOSE ��Ϣ֮ǰ���� onclose����������Ԥ�� send_notification �����з����ܵ��𻵴��󡣲��ҵ��ǣ����� onclose �� Firefox ���������ã������Ա����������� Chrome �д򿪸�Ӧ�ó���ʱ������ send_notification �����л����˹ܵ��𻵴������������� Google Chrome �е�һ��δ������������

4��һ���־õ� WebSocket ����


onclose �͹ر�֡��������ʹ���Dz��õ�һ���־õ� WebSocket ���ӡ����ڽ����������뿪ҳ�棨ͨ���رմ��ڡ����¼��ػ�ת����һ�� URL��ʱ�Ż��رյĵ�һ���ӣ�ֻҪ�����ͷ������ڷ����ܵ�����ʱ�ر����ӡ�һ�����л����Ӹ������� Project WoK ��ά�������� WoK ����ʹ����������ͷʵ�� WebSocket ���ԡ�

�嵥 10 ������һ�������޸ĵ� send_notification ��Ϣ����ע�⣬�������ܵ��𻵴����ķ�ʽ�ǣ�����Ч�����б���ɾ���׽��֣�Ȼ���ر�����

�嵥 10. ���Ե����־����ӵ� send_notification��
def send_notification(self, message):
for sock in self.connections:
    if sock != self.server_socket:
        try:
            sock.send(message)
        except IOError as e:
            if 'Broken pipe' in str(e):
                sock.close()
                try:
                    self.connections.remove(sock)
                except ValueError:
                    pass


5���������ź���Ϣ


�ڶ����Ӳ����У���������һ�����ӣ�ʹ������Ȼ�������ر����������־�����Ӧ�����ڵر��ִ򿪣���ʹû�з����κ���Ϣ�����ǣ�Chrome �� Firefox �еIJ��Ա�����WebSocket ���ӻ��ڿ���һ��ʱ������ʱ���������ӻ���ֹ��

Ϊ�˱�����������ʱ������ʵ����һ���򵥵������ź���Ϣ�����������ͷ��������͸���Ϣ������Ϣʹ WebSocket ���ӱ��ֻ �� ���ͷ���������Ҫ��Ӧ����Ĭ�ϳ�ʱ��ԼΪ 300 �룬�����Dz��ܼ���������������ʵ����ͬ�ij�ʱ��Ϊ��ȫ���������ǽ������ź���Ϣ���ͼ�������Ϊ 30 �룬���嵥 11 ��ʾ��

�嵥 11. ��ʱ������
notificationsWebSocket = new WebSocket(url, ['base64']);
var heartbeat = setInterval(function() {
    notificationsWebSocket.send(window.btoa('heartbeat'));
}, 30000);

�����򵥵ij�ʱ��ʹ WebSocket ���ӱ��ֻ�����Ҳ��������ͷ��������͹��������ź���Ϣ��

6���Ӽ�����


�����������Ӻ󣬿���ʵ��һ���򵥵ļ��������ԣ�����ʾ��Ӧ�ó����е��������� UI ����������Ϣ��

�����Ǹò��Ե����ƣ�

  • һ���������󶨵�һ���ض���Ϣ��ʽ�����ǵ�ʾ��Ӧ�ó��򽫷�������֪ͨ��Ϣ����Ϣ����ʹ�����ܽ�Ϊ�ض���Ϣע����������
  • �յ��������ͷ���������Ϣ������Ҫ WebSocket ͨ����֤�������ݣ�������������Ϣ�󶨵����м�������
  • WebSocket ͨ������������������������������ URI ���ĺ����á����磬���û������� URI /#tabs/settings �е� Settings ѡ�ʱ��Ӧ���� URI /#tabs/user-log �е� Activity Log ѡ��ϵ��������������������󶨵� hashchange �¼��� URL (location.hash) ÿ�θ���ʱ���ᴥ�����¼�����Ϊ����ֻ���Դ˹���ִ��һ�Σ����Կ��Խ� $.one()�� jQuery ��������Ϊ��ִ��һ�Ρ�

������ʾ��Ӧ�ó����д����������Ĵ��롣

�嵥 12. Project WoK �ļ��������ã�
wok.notificationListeners = {};
wok.addNotificationListener = function(msg, func) {
    var listenerArray = wok.notificationListeners[msg];
    if (listenerArray == undefined) {
        listenerArray = [];
    }
    listenerArray.push(func);
    wok.notificationListeners[msg] = listenerArray;
    $(window).one("hashchange", function() {
        var listenerArray = wok.notificationListeners[msg];
        var del_index = listenerArray.indexOf(func);
        listenerArray.splice(del_index, 1);
        wok.notificationListeners[msg] = listenerArray;
    });
};

�����ǽ���Ϣ���͵�ÿ�����ؼ������ķ�ʽ��

�嵥 13. ������֪ͨ��
wok.startNotificationWebSocket = function () {
    wok.notificationsWebSocket = new WebSocket(url, ['base64']);
    wok.notificationsWebSocket.onmessage = function(event) {
        var message  = window.atob(event.data);
         if (message === "") {
                continue;
        }
              
        var listenerArray = wok.notificationListeners[message];
        if (listenerArray == undefined) {
            continue;
        }
        for (var i = 0; i < listenerArray.length; i++) {
            listenerArray[i](message);
        }
    }
 };

���˸�֪ͨ�����ǵIJ����ͻ����������ˡ������Ȼ���Ҫ����һ�����⡣

7�ϲ���Ϣ


���ܿ���ʹ�õ�һ���ӣ�����ǰʵ�ֶ�ǰ�����ν�����Ϣ�����˲������ļ��衣�������ͷ���������������������Ϣ���ȷ��� message1��Ȼ������ message2������������������Ҫ�󴥷� onmessage �¼����β��� WebSocket �ж�ȡ���ݣ�����ʵδ�����ˡ���ʵ�ϣ������ܵ������ǣ��յ�����Ϣ�� message1message2�� һ���ϲ���Ϣ��

�ϲ���Ϣ��һ�ֳ����� TCP �׽�����Ϊ������������������������Ϣʱ�������׽��ֻ������ǽ����Ŷӣ����ҽ�Ϊ������Ϣ���� onmessage �¼�һ�Ρ���������δ�Դ��ƶ�Ӧ�Լƻ�������Ϊ���ƻ����ǵĴ��롣���������Ƕ���һ����Ϣ��ʽ����Ӧ�ó���ȷ��һ����Ϣ�ںδ���������һ����Ϣ�ںδ���ʼ��

һ�����е�ѡ���� TLV ��ʽ����ʾ����-����-ֵ (Type-Length-Value)���ڴ˸�ʽ�У���Ϣ���ΰ��� 3 ���ֶΣ�type��length �� value�����ͺͳ��Ⱦ��й̶���С��ֵ���� length �ֶ��������Ŀɱ���С��type �ֶο�����������Ϣ���ͣ������ַ���������ֵ�������ƻ���������Ҳ�������ض���Ӧ�ó�������;�����羯����Ϣ����Ϣ��Ϣ��������Ϣ�ȡ�

���ǣ������Ƕ��ԣ�TLV �е�����С�á����ǵ���Ϣʼ�����ַ��������Բ���Ҫ type �ֶΡ�Ϊ�˽�����Ϣ�Ĵ������⣬��������һ���̶����ȵ��ֶΣ�����������Ϣ�������ٸ��ַ���һ�ָ��򵥵ķ����ǣ������͵�ÿ����Ϣ����һ����Ϣ�������ǡ��յ���Ϣ��������ǰ��ʹ����Ϣ���ǽ���������������Ϊ������ǰ����Ϣ��

�嵥 14 �������޸ĺ��� send_notification ���������а���һ����Ϣ�������ǡ�

�嵥 14. send_notification �е���Ϣ�������ǣ�
END_OF_MESSAGE_MARKER = '//EOM//'
  
    def send_notification(self, message):
        message += END_OF_MESSAGE_MARKER
        for sock in self.connections:
            if sock != self.server_socket:
                try:
                    sock.send(message)
                except IOError as e:
                    if 'Broken pipe' in str(e):
                        sock.close()
                        try:
                            self.connections.remove(sock)
                        except ValueError:
                            pass

��ע���嵥 14 �е� //EOM// ���С�����ʹ���κ���������ʾ��Ϣ������ֻҪ�����ǰ�������Ч��Ϣ�е����� �� ���� end��

�嵥 15 ��������������Ϣ��β�������������ɵ�ǰ�˴��롣������ Project WoK ����ȡ����Դ���롣

�嵥 15. WebSocket ǰ�ˣ�
wok.notificationListeners = {};
wok.addNotificationListener = function(msg, func) {
    var listenerArray = wok.notificationListeners[msg];
    if (listenerArray == undefined) {
        listenerArray = [];
    }
    listenerArray.push(func);
    wok.notificationListeners[msg] = listenerArray;
    $(window).one("hashchange", function() {
        var listenerArray = wok.notificationListeners[msg];
        var del_index = listenerArray.indexOf(func);
        listenerArray.splice(del_index, 1);
        wok.notificationListeners[msg] = listenerArray;
    });
};
  
wok.notificationsWebSocket = undefined;
wok.startNotificationWebSocket = function () {
    var addr = window.location.hostname + ':' + window.location.port;
    var token = wok.urlSafeB64Encode('woknotifications').replace(/=*$/g, "");
    var url = 'wss://' + addr + '/websockify?token=' + token;
    wok.notificationsWebSocket = new WebSocket(url, ['base64']);
  
    wok.notificationsWebSocket.onmessage = function(event) {
        var buffer_rcv = window.atob(event.data);
        var messages = buffer_rcv.split("//EOM//");
        for (var i = 0;  i < messages.length; i++) {
            if (messages[i] === "") {
                continue;
            }
            var listenerArray = wok.notificationListeners[messages[i]];
            if (listenerArray == undefined) {
                continue;
            }
            for (var j = 0; j < listenerArray.length; j++) {
                listenerArray[j](messages[i]);
            }
        }
    };
  
    var heartbeat = setInterval(function() {
        wok.notificationsWebSocket.send(window.btoa('heartbeat'));
    }, 30000);
  
};

8��������


����ֻ��Ҫ�����ͻ��˴����첽��������Ϣ�� Web Ӧ�ó��򣬷��������͵��¼���һ�������Ҽ򵥵Ľ�����������Ϊ��˫�� HTTP ����������SSE �������ͻ������������ش���Ϣ�����⣬�ڱ�д����ʱ������ Microsoft ����������֧�� SSE���������Ƿ����������㣬ȡ����Ӧ�ó�����Ŀ�����ڡ�

WebSocket ��������Ҫ�����ߣ���ȫ˫�� TCP ����ʹ�������ڸ��㷺��Ӧ�ó�����WebSocket �ܴ������ִ� Web ����֧�֣����Ҽ���������Ҫ�� Web ���ƶ�������������û����ʾ��������ʹ������ Tornado �����ķ��������ܣ��������ڿ����������ͷ���������������ͷ��д���������롣

SSE ��һ���������Ҹ����Ľ��������������Dz�����չ�ġ����� Web Ӧ�ó��������������˸ı䣨���磬��������Ϊǰ��Ӧ�����˽�����������Ҫʹ�� WebSocket �ع�Ӧ�ó�����WebSocket ��Ҫ��������ǰ�ڹ�����������һ�ָ������ġ�����չ�Ŀ��ܡ������ʺϻ᲻�������¹��ܵĸ���Ӧ�ó�����

9����������


��д WebSocket ������
Web ���ƶ��������Է��������͵��¼���֧��
Web ���ƶ��������� WebSocket Э����֧��

��ԭ�����ӣ�https://www.ibm.com/developerworks/cn/web/wa-http-server-push-with-websocket-sse/index.html��

��ʱͨѶ�� - ��ʱͨѶ������������ ��Դ�� - ��ʱͨѶ������������

��һƪ���Ÿ��Ŷ�ԭ����һ���߹� iOS10 ����Ϣ����(APNS)�Ŀ���һƪ��С��������UDP������Ϣ���͵Ŀ�����

��������¼�����¼���ר��

�Ƽ�����
���� 7
�ܲ��������ϣ���Ȼ�����˵�python��������������ԭ���н�������
ǩ��: �û�Աû����д������˵����.
��������
�dz��õ����£���л�ˡ�
��ʾ: ����������Ա����������
����
ǩ��: ��
��ʾ: ����������Ա����������
���ã�xiaoyan2017 ������ 2019-03-14 11:10
�ܰ��ķ�����ѧϰ���˺ܶ�֪ʶ�������໥ѧϰ�¡�
https://www.cnblogs.com/xiaoyan2017/p/10163043.html

�����Ǽ��������ز岥���Ĺ��氡
ǩ��: ����Ϊ��֪����������(��ʮ)������ping��ͨ�����ж���ԭ����һ�ĸ����ף���http://www.52im.net/thread-4857-1-1.html
����¥�� ×
ʹ��΢�Ŵ��ͣ� ʹ��֧�������ͣ�

���ض���