2025年3月24日 星期一 甲辰(龙)年 月廿三 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 编程开发 > Python

python socketio客户端与服务端连接方式

时间:08-17来源:作者:点击数:23

1.socketio和websocket 的区别

WebSocket是一种通信协议,它通过TCP连接在客户端和服务器之间提供双向通信,WebSocket连接始终保持打开状态,因此它们允许实时数据传输。当客户端向服务器触发请求时,它不会在接收到响应时关闭连接,而是会持续存在并等待客户端或服务器终止请求。

本文章介绍flask socketio 和tornado websocket使用例子 

Socket.IO 是一个库,可用于在客户端和Web服务器之间进行实时和全双工通信。它使用WebSocket协议提供接口。通常,它分为两部分,WebSocketSocket.io都是事件驱动的库.

简单说 socketio 是对websocket的封装 服务端用socketio客户端也要用socketio 服务端用websocket客户端也要用websocket

SocketIO时,不用担心兼容问题,底层会自动选用最佳的通信方式。因此说,WebSocket是SocketIO的一个子集。

broadcast 为True 进行全员广播

ws.emit('user_message', {"test_111": random.randint(1, 10), "ut": ut}, broadcast=True)

所需要的安装包

  • python-engineio==3.13.1
  • python-socketio==4.6.0
  • Flask-SocketIO==4.3.1
  • Werkzeug==1.0.1
  • flask==1.0.2

客户端连接方式

  • import socketio
  • sio = socketio.Client()
  • ut = "1"
  • @sio.event
  • def connect():
  • print('connection established')
  • # 监听服务端推送消息
  • @sio.event
  • def user_message(data):
  • print('user_message received with ', data)
  • # sio.emit('my response', {'response': 'my response'})
  • @sio.event
  • def disconnect():
  • print('disconnected from server')
  • # 连接服务端 IP+端口
  • sio.connect('http://localhost:8091')
  • print("000")
  • # 向服务端发送消息
  • sio.emit('sub_user_message', ut)
  • sio.wait()

服务端起socketio方式

  • # -*- coding: utf8 -*-
  • # socketio要想与flask通信必须打补丁
  • from gevent import monkey
  • monkey.patch_all()
  • print('monkey.patch_all()')
  • from flask import Flask
  • from werkzeug.utils import import_string
  • from flask_socketio import SocketIO
  • import flask_socketio as ws
  • import time
  • webapp = Flask(__name__, static_url_path='/static')
  • webapp.config.from_object("config.Default") # 引入配置文件config.py 下Default 对象
  • try:
  • local_cfg = import_string('local_cfg.Config')
  • webapp.config.from_object(local_cfg)
  • except:
  • pass
  • webapp.debug = webapp.config.get("DEBUG", False)
  • webapp.testing = webapp.config.get("TESTING", False)
  • webapp.static_folder = webapp.config.get('STATIC_BASE', 'static')
  • webapp.template_folder = webapp.config.get('TEMPLATE_BASE', './templates')
  • REDIS_HOST = '127.0.0.1'
  • REDIS_PORT = 6379
  • REDIS_DB = 10
  • SOCKETIO_MESSAGE_QUEUE = 'redis://:@%s:%d/%d' % (
  • REDIS_HOST, REDIS_PORT, REDIS_DB) # 通过redis 实现socketio 与flask 进行通信 必须要打补丁
  • # 无论是否是在WSAPP的环境中,
  • # 都需要初始化socket_io,
  • # 因为WEBAPP需要通过它和WSAPP进行通信
  • socket_io = SocketIO(webapp, cors_allowed_origins='*', message_queue=SOCKETIO_MESSAGE_QUEUE)
  • @socket_io.on('connect')
  • def msg_connect():
  • print("111111 connect")
  • ws.emit('msg_connect', {'data': 'Connected'})
  • ut = "1"
  • if ut:
  • ws.join_room('wx_scan_login.' + ut)
  • @socket_io.on('sub_user_message')
  • def sub_user_message(*args, **kwargs):
  • """
  • 用户需要登录访问加到user_message 房间判断用户登录
  • :return:
  • """
  • print(*args)
  • print("sub_user_message")
  • ut = str(args)
  • if ut:
  • # 加入房间 房间名称 user_message.
  • # 服务端对用户按要求加入不同房间 一个用户一个房间或多个用户一个房间
  • ws.join_room('user_message.' + ut)
  • while True:
  • # 客户端向服务端推送消息 事件名称为:user_message 客户端要监听此事件
  • ws.emit('user_message',
  • {'data': {'status': 0, 'msg': '支付失败'}, 'command': 'pay'},
  • room='user_message.' + ut)
  • time.sleep(1)
  • import random
  • if ut == "12345": # broadcast为True,进行全员广播,调用一次全员广播一次
  • ws.emit('user_message', {"test_111": random.randint(1, 10), "ut": ut}, broadcast=True)
  • @socket_io.on('disconnect')
  • def msg_disconnect():
  • print('Client disconnected')
  • socket_io.run(webapp, host='127.0.0.1', port=8091)

获取断开用户的id 可以flask 上下文设置

Tornado websocket

server 

  • #!/usr/bin/env python
  • # -*- coding: utf-8 -*-
  • import logging
  • import tornado.web
  • import tornado.websocket
  • import tornado.ioloop
  • import tornado.options
  • from tornado.options import define, options
  • define("port", default=3000, help="run on the given port", type=int)
  • class Application(tornado.web.Application):
  • def __init__(self):
  • handlers = [(r"/", MainHandler)]
  • settings = dict(debug=True)
  • tornado.web.Application.__init__(self, handlers, **settings)
  • class MainHandler(tornado.websocket.WebSocketHandler):
  • def check_origin(self, origin):
  • return True
  • def open(self):
  • logging.info("A client connected.")
  • def on_close(self):
  • logging.info("A client disconnected")
  • def on_message(self, message):
  • logging.info("message: {}".format(message))
  • def main():
  • tornado.options.parse_command_line()
  • app = Application()
  • app.listen(options.port)
  • tornado.ioloop.IOLoop.instance().start()
  • if __name__ == "__main__":
  • main()

client

  • #!/usr/bin/env python
  • # -*- coding: utf-8 -*-
  • from tornado.ioloop import IOLoop, PeriodicCallback
  • from tornado import gen
  • from tornado.websocket import websocket_connect
  • class Client(object):
  • def __init__(self, url, timeout):
  • self.url = url
  • self.timeout = timeout
  • self.ioloop = IOLoop.instance()
  • self.ws = None
  • self.connect()
  • PeriodicCallback(self.keep_alive, 20000).start()
  • self.ioloop.start()
  • @gen.coroutine
  • def connect(self):
  • print "trying to connect"
  • try:
  • self.ws = yield websocket_connect(self.url)
  • print ""
  • except Exception, e:
  • print "connection error"
  • else:
  • print "connected"
  • self.run()
  • @gen.coroutine
  • def run(self):
  • while True:
  • msg = yield self.ws.read_message()
  • print "msg:",msg
  • if msg is None:
  • print "connection closed"
  • self.ws = None
  • break
  • def keep_alive(self):
  • if self.ws is None:
  • self.connect()
  • else:
  • self.ws.write_message("keep alive")
  • if __name__ == "__main__":
  • client = Client("ws://localhost:8061/notify/anonymous?ut=RRYhwCzTbAi3945zsNjv", 5)
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐