即時通信(二)

Socket.IOpython

    Socket.IO本是一個面向實時web應用的JavaScript庫,如今已經成爲擁有衆多語言的Web即時通信應用框架。程序員

    Socket.IO 主要使用WebSocket協議。可是若是須要的話,Socket.io能夠回退到幾種其它方法,例如Adobe Flash Sockets,JSONP拉取,或是傳統的AJAX拉取,而且在同時提供徹底相web

               同的接口。儘管它能夠被用做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要求客戶端與服務器端                均須使用該框架。app

我是一個python 工做者,那實際在python中怎麼使用呢?框架

  1. 首先要安裝 pip install python-socketio
  2. 建立服務器
    1.   方式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()
相關文章
相關標籤/搜索