python socketio客户端与服务端连接方式
1.socketio和websocket 的区别
WebSocket
是一种通信协议,它通过TCP连接在客户端和服务器之间提供双向通信,WebSocket连接始终保持打开状态,因此它们允许实时数据传输。当客户端向服务器触发请求时,它不会在接收到响应时关闭连接,而是会持续存在并等待客户端或服务器终止请求。
本文章介绍flask socketio 和tornado websocket使用例子
Socket.IO
是一个库,可用于在客户端和Web服务器之间进行实时和全双工通信。它使用WebSocket
协议提供接口。通常,它分为两部分,WebSocket
和Socket.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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
2018-06-29 Django Aggregation聚合 django orm 求平均、去重、总和等常用方法
2018-06-29 nohup 后台启动程序,并输出到指定日志
2017-06-29 linux 技巧:使用 screen 管理你的远程会话(短时间内同时开启多个会话)