python+react实现websocket通信
一、服务端(二选一)
python flask版
- 踩坑:
socket.io
这个包好像并不完全遵循ws协议,在线的websocket无法连接由socket.io
创建的服务器 - 使用
geventwebsocket
包- 安装库
> pip install gevent-websocket > pip install flask
- 使用
from flask import Flask, request from geventwebsocket import WebSocketError from geventwebsocket.handler import WebSocketHandler from geventwebsocket.websocket import WebSocket from geventwebsocket.server import WSGIServer import time app = Flask(__name__) app.config['SECRET_KEY'] = 'secret!' @app.route("/ws") def ws(): sock = request.environ.get("wsgi.websocket") # type: WebSocket while True: try: msg = sock.receive() if msg: print(msg) except WebSocketError: break return "200ok" @app.route("/receive") def send(): sock = request.environ.get("wsgi.websocket") # type: WebSocket while True: localtime = time.asctime( time.localtime(time.time()) ) try: sock.send(localtime) time.sleep(1) except WebSocketError: break return "200ok" if __name__ == '__main__': http_serv = WSGIServer(("0.0.0.0", 9527), app, handler_class=WebSocketHandler) http_serv.serve_forever()
- 安装库
python tornado版
- 代码
import logging, os.path import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web import tornado.websocket import tornado.gen class Application(tornado.web.Application): def __init__(self): base_dir = os.path.dirname(__file__) app_settings = { "debug": True, 'static_path': os.path.join(base_dir, "static"), } tornado.web.Application.__init__(self, [ tornado.web.url(r"/", MainHandler, name="main"), tornado.web.url(r"/live", WebSocketHandler, name="websocket"), ], **app_settings) class MainHandler(tornado.web.RequestHandler): def get(self): self.render('index.html') class WebSocketHandler(tornado.websocket.WebSocketHandler): listenners = [] def check_origin(self, origin): return True @tornado.gen.engine def open(self): WebSocketHandler.listenners.append(self) def on_close(self): if self in WebSocketHandler.listenners: WebSocketHandler.listenners.remove(self) @tornado.gen.engine def on_message(self, wsdata): for listenner in WebSocketHandler.listenners: listenner.write_message(wsdata) @tornado.gen.coroutine def main(): tornado.options.parse_command_line() http_server = tornado.httpserver.HTTPServer(Application()) http_server.listen(8888) logging.info("application running on http://localhost:8888") if __name__ == "__main__": tornado.ioloop.IOLoop.current().run_sync(main) tornado.ioloop.IOLoop.current().start()
二、客户端(React脚手架)
- 利用react脚手架创建项目
- 下载
react-websocket
依赖库> npm install react-websocket --save
- 修改
App.js
的代码// App.js import './App.css'; import WebSocket from 'react-websocket' import React, {Component} from 'react' class App extends Component{ state = { text: "", msg: "" } handleChange = (e) => { this.setState({ text: e.target.value }) } handleClick = () => { this.send.sendMessage(this.state.text) this.setState({ text: "" }) } handleMessage = (msg) => { this.setState({ msg }) } render() { return ( <div> <h1>{this.state.msg}</h1> <input type="text" placeholder="text" value={this.state.text} onChange={this.handleChange}/> <input type="submit" onClick={this.handleClick}/> <WebSocket url="ws://127.0.0.1:9527/ws" onMessage={this.handleMessage} ref={websocket => this.send = websocket} /> <WebSocket url="ws://127.0.0.1:9527/receive" onMessage={this.handleMessage}/> </div> ); } } export default App;
参考:
https://github.com/mehmetkose/react-websocket