即时通信(二)

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()
相关文章
相关标签/搜索