三种通信模型的简要说明:

(1) 轮询:

客户端以高频率周期性地连续向服务器发送请求:

客户端请求 - 服务器响应 - 断开连接。请求QPS比较频繁,对client和server的配置要求比较高

(2) 长轮询:

客户端定期连续向服务器发送请求:

客户端和服务端的连接会保持一段时间,所以请求不会特别频繁

(3) 长连接:

客户端与服务端建立连接后,如果不是特殊原因(客户端主动断开,服务端出现故障),连接会一直保持

同时通过多线程的IO复用技术解决并发问题

flash中基于gevent websocket的IO复用技术的长连接通信:

(1)基于gevent websocket的IO多路长连接通信,需要导入以下模块:

#PIP install gevent websocket 导入IO复用模块

from geventwebsocket.handler import WebSocketHandler #提供WS(websocket)协议处理

从 ventwebsocket.server 导入 WSGIServer #websocket 服务承载

#WSGIServer 导入的是 pywsgi 中的 gevent 类

from vent.pywsgi 导入 WSGIServer

from geventwebsocket.websocket import WebSocket #websocket 语法提示

(2) 路由视图函数中的处理必须通过请求环境。 get('wsgi.websocket') 用client_socket获取ws连接客户端:

#websocket协议通信如下(http请求可以正常处理)

@app.route()

定义函数():

客户端_socketu003drequest.environ.get('wsgi.websocket')

而 1:

客户端\socket.receive()

...

客户端_socket.send(str)

...

(3)flash项目启动如下:

WSGIServer 默认处理 http 请求。 http在路由视图中可以正常使用,

但是,在使用 ws 协议时,一定要传递请求。在视图函数环境中。 get('wsgi.websocket') 获取ws连接客户端与client_socket,

通过_Socket client_socket.recive()/client_socket.send()通信连接客户端,会自动对字符串进行编码和解码)

http_serveru003dWSGIServer(('192.168.16.14',8888),applicationu003dapp,handler_classu003dWebSocketHandler.

http_server.serve_forever()

(4)前端页面使用js发出WS(websocket)请求:

浏览器提供websocket客户端,直接通过new创建到ws的websocket连接(ws状态码0表示连接已创建但未连接,1表示连接仍在进行中,2表示客户端主动断开,而3表示服务器断开) onmessage u003d function (messageevent) {} 监听并执行回调函数获取信息messageevent数据,通过ws Send()发送消息。

<脚本>

var ws u003d new WebSocket('ws://192.168.16.14:8888/websocket');

ws.onmessage u003d 函数(消息事件){

控制台日志(消息事件);

控制台.log(MessageEvent.data);

};

函数发送() {

var msg u003d document.getElementById('msg').value;

ws.send(味精);

}

</脚本>

http请求协议和websocket请求协议Environ的请求原始数据请求与请求头信息request Headers对比:

http环境:

{

'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6',

'SCRIPT_NAME': '', 'wsgi.version': (1, 0),

'wsgi.multithread':假,'wsgi.multiprocess':假,

'wsgi.run_once':假,'wsgi.url_scheme':'http',

'wsgi.errors': <_io.TextIOWrapper nameu003d'<stderr>' modeu003d'w' encodingu003d'UTF-8'>,

'SERVER\NAME': 'PC-Yang', 'SERVER_PORT': '8888', 'REQUEST_METHOD': 'GET',

'PATH_INFO': '/websocket', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1',

'REMOTE_ADDR': '192.168.16.14', 'REMOTE_PORT': '61539', 'HTTP_HOST': '192.168.16.14:8888',

'HTTP_CONNECTION':'keep-alive','HTTP_PRAGMA':'无缓存','HTTP_CACHE_CONTROL':'无缓存',

'HTTP_UPGRADE_INSECURE_REQUESTS': '1',

'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',

'HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;qu003d0.9,image/webp,image/apng,*/*;qu003d0.8,application/signed-exchange; vu003db3',

'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;qu003d0.9',

'wsgi.input': <gevent.pywsgi.Input object at 0x03A9DC00>,

'wsgi.input_terminated':真,'werkzeug.request':<请求'http://192.168.16.14:8888/websocket'[GET]>

}

http标头:

'''

主机:192.168.16.14:8888

连接:保持活动

编译指示:无缓存

缓存控制:无缓存

升级-不安全-请求:1

用户代理:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36

接受:text/html,application/xhtml+xml,application/xml;qu003d0.9,image/webp,image/apng,*/*;qu003d0.8,application/signed-exchange;vu003db3

接受编码:gzip、deflate

接受语言:zh-CN,zh;qu003d0.9

websocket-environ: 'wsgi.websocket': <geventwebsocket.网络套接字。 Websocket 对象位于 0x03a9dc00 >,websocket 连接

'''

{

'GATEWAY_INTERFACE': 'CGI/1.1', 'SERVER_SOFTWARE': 'gevent/1.4 Python/3.6',

'SCRIPT_NAME': '', 'wsgi.version': (1, 0), 'wsgi.multithread': False,

'wsgi.multiprocess':假,'wsgi.run_once':假,'wsgi.url_scheme':'http',

'wsgi.errors': <_io.TextIOWrapper nameu003d'<stderr>' modeu003d'w' encodingu003d'UTF-8'>,

'SERVER\NAME': 'PC-Yang', 'SERVER_PORT': '8888', 'REQUEST_METHOD': 'GET',

'PATH_INFO': '/websocket', 'QUERY_STRING': '', 'SERVER_PROTOCOL': 'HTTP/1.1',

'REMOTE_ADDR':'192.168.16.14','REMOTE_PORT':'61591','HTTP_HOST':'192.168.16.14:8888',

'HTTP_CONNECTION':'升级','HTTP_PRAGMA':'无缓存','HTTP_CACHE_CONTROL':'无缓存',

'HTTP_USER_AGENT': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36',

'HTTP\UPGRADE': 'websocket', 'HTTP_ORIGIN': 'http://192.168.16.14:8888', 'HTTP_SEC_ WEBSOCKET\VERSION': '13',

'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'zh-CN,zh;qu003d0.9',

'HTTP_SEC_WEBSOCKET_KEY': 'Oyfq0MCEBnsypKstjjRvYgu003du003d',

'HTTP_SEC_WEBSOCKET_EXTENSIONS': 'permessage-deflate;客户端_max_window_bits',

'wsgi.input': <gevent.pywsgi.Input object at 0x03A9DCA8>,

'wsgi.input_terminated':真,'wsgi.websocket_version':'13',

'wsgi.websocket': <geventwebsocket.websocket.WebSocket 对象在 0x03A9DC00>,

'tool.request': <请求'http://192.168.16.14:8888/websocket' [GET]>

}

'''

Websocket 标头:升级:Websocket #websocket 请求中的标识

'''

主机:192.168.16.14:8888

连接:升级

编译指示:无缓存

缓存控制:无缓存

用户代理:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36

升级:websocket #Identification in websocket request

来源:http://192.168.16.14:8888

Sec-Websocket-版本:13

接受编码:gzip、deflate

接受语言:zh-CN,zh;qu003d0.9

Sec-Websocket-Key: Oyfq0MCEBnsypKstjjRvYgu003du003d

Sec-Websocket-Extensions:permessage-deflate;客户端_max_window_bits

'''

websocket-headers

(1) 基于websocket+Flash的无昵称群聊即时通讯

烧瓶_websocket(MUC_Nonick).py

1 '''

2 基于websocket+flask 群聊和无昵称即时通讯

3 设计列表client_list u003d []来存储客户端和服务端的连接,

4 服务接收到任意客户端的信息(信息)时,遍历连接存储列表,获取每个连接,直接转发

5'''

6 from flask import Flask, render_template, request

7

8 # PIP install gevent websocket 导入IO复用模块

9 from geventwebsocket.handler import WebSocketHandler #提供WS(websocket)协议处理

10 from ventwebsocket.server import WSGIServer # websocket 服务承载

11 # WSGIServer 导入的是 pywsgi 中的 gevent 类

12 # 从 vent.pywsgi 导入 WSGIServer

13 from geventwebsocket.websocket import WebSocket #websocket语法提示

14

15 应用程序 u003d 烧瓶(__name__)

16

17 # @app.route('/websocket')

18 # 多个客户端可以同时向假服务器发送ws协议信息

19 # def websocket():

20 # 客户端_socketu003drequest.environ.get('wsgi.websocket') #type:WebSocket

21 # 而 1:

22 # msg\from\cliu003dclient\socket.receive()

23 # 打印(味精\来自\cli)

24 # 多个客户端可以同时向虚假服务器发送ws协议信息,服务器将信息转发到各个客户端页面,实现多人聊天室的即时通讯

25 客户\列表 u003d []

26

27

28 @app.route('/websocket')

29 定义 websocket():

30 client_socket u003d request.environ.get('wsgi.websocket') # type:WebSocket

31 客户端\list.append(客户端_socket)

32 # 打印(len(client\list), client\list)

33 而 1:

34 msg\from\cli u003d client\socket.receive()

35 # 打印(味精\来自\cli)

36 #所有从任意客户端收到的信息都会被转发(注意如果客户端断开连接,在遍历和发送过程中连接不存在会报错,需要异常处理)

37 对于客户端\列表中的客户端:

38 次尝试:

39 client.send(msg_from_cli)

40 例外为 e:

41 继续

42

43 @app.route('/聊天')

44 定义聊天():

45 返回渲染_template('MUC_Nonick.html')

46

47

48 如果 __name__ u003du003d '__main__':

49 # app.run('192.168.16.14',8888,debugu003dTrue)

50 http_server u003d WSGIServer(('192.168.16.14', 8888), applicationu003dapp, handler_classu003dWebSocketHandler)

51 http_server.serve_forever()

烧瓶_websocket(MUC_Nonick).py

MUC_Nonick.html

1 <!DOCTYPE html>

2 <HTML浪u003d"恩">

3 <头部>

4 <元字符集u003d"UTF-8">

5 <title>多用户无昵称聊天</title>

6 </head>

7 <身体>

8 <div idu003d"chat_room">

9 <p>请输入聊天内容:<input typeu003d"text" idu003d"msg">

10 <button idu003d"send" onclicku003d"send()">发送</button>

11 </p>

12 <div idu003d"chat_content"></div>

13 </div>

14 </正文>

15 <脚本类型u003d"应用程序/javascript">

16 var ws u003d new WebSocket('ws://192.168.16.14:8888/websocket');

17 ws.onmessage u003d 函数(消息事件){

18 //console.log(MessageEvent);

19 //console.log(MessageEvent.data);

20 var timeu003dnew Date();

21 var tu003d time.toLocaleString();

22 var pu003ddocument.createElement("p");

23 p.innerTextu003d"("+t+")"+MessageEvent.data;

24 document.getElementById('chat_content').appendChild(p);

25 };

26

27 函数发送(){

28 var msg u003d document.getElementById('msg').value;

29 ws.send(msg);

30 }

31 </脚本>

32 </html>

MUC_Nonick.html

(2)基于websocket+Flash的带昵称的群聊即时通讯

版本一:通过动态路径参数获取客户端昵称:

烧瓶_websocket(MUC_nick_route).py

1 '''

2 基于websocket+flask的群聊即时通讯

3 设计字典client_dict u003d {}来存储{Client Name: 客户端与服务端的连接},通过动态路由参数获取客户端名称,

4 服务端接收到客户端的信息(通过 json 序列化的字典)遍历存储连接信息的字典,获取客户端的连接并直接转发

5'''

6 from flask import Flask, render_template, request

7 from geventwebsocket.handler import WebSocketHandler #提供WS(websocket)协议处理

8 from ventwebsocket.server import WSGIServer # websocket 服务承载

9 from geventwebsocket.websocket import WebSocket #websocket语法提示

10

11 应用程序 u003d 烧瓶(__名称__)

12

13 客户_dict u003d {}

14

15

16 @app.route('/websocket/<client_name>')#通过动态路由参数获取昵称,必须在视图函数中定义同名的形参

17 def websocket(client_name):

18 client_socket u003d request.environ.get('wsgi.websocket') # type:WebSocket

19 客户端_dict[客户端_name] u003d 客户端_socket

20 # 打印(len(client_dict), client_dict)

21 而 1:

22 msg\from\cli u003d client\socket.receive()

23 用于 client_dict.values() 中的客户端:

24 次尝试:

25 client.send(msg_from_cli)

26 例外为 e:

27 继续

28

29

30 @app.route('/聊天')

31 定义聊天():

32 返回渲染_template('MUC_nick_route.html')

33

34

35 如果 __name__ u003du003d '__main__':

36 # app.run('192.168.16.14',8888,debugu003dTrue)

37 http_server u003d WSGIServer(('192.168.16.14', 8888), applicationu003dapp, handler_classu003dWebSocketHandler)

38 http_server.serve_forever()

烧瓶_websocket(MUC_nick_route).py

MUC_nick_route.html

1 <!DOCTYPE html>

2 <HTML浪u003d"恩">

3 <头部>

4 <元字符集u003d"UTF-8">

5 <title>多用户无昵称聊天</title>

6 </head>

7 <身体>

8 <div idu003d"chat_room">

9 <p>输入你的昵称进入多人聊天室:<input typeu003d"text" idu003d"client_name"></input>

10 <button idu003d'login' onclicku003d"login()">登录</button>

11 </p>

12 <p idu003d'chat_msg' hiddenu003d"hidden">请输入聊天内容:<input typeu003d"text" idu003d"msg">

13 <button idu003d"send" onclicku003d"send()">发送</button>

14 </p>

15 <div idu003d"chat_content" hiddenu003d"hidden"></div>

16 </div>

17 </正文>

18 <脚本类型u003d"应用程序/javascript">

19 变量 ws u003d 空;

20 变量名称u003d空;

21

22 函数登录() {

23 document.getElementById('login').setAttribute('hidden', 'hidden');

24 document.getElementById('client_name').setAttribute('disabled', 'disabled');

25 document.getElementById('chat_msg').removeAttribute('hidden');

26 document.getElementById('chat_content').removeAttribute('hidden');

27 name u003d document.getElementById('client_name').value;

28 //WS实例化

29 ws u003d new WebSocket('ws://192.168.16.14:8888/websocket/' + 名称);

30

31 //监听来自服务器的消息(json数据)

32 ws.onmessage u003d 函数(消息事件){

33 //console.log(MessageEvent);

34 //console.log(MessageEvent.data);

35 var 内容_str u003d JSON.parse(MessageEvent.data);

36 var time u003d new Date();

37 var t u003d time.toLocaleTimeString();

38 var p u003d document.createElement("p");

39 p.innerText u003d 内容_str.name + "(" + t + "):" + 内容_str.msg;

40 document.getElementById('chat_content').appendChild(p);

41};

42};

43

44

45 //聊天消息发送(json数据)

46 函数发送(){

47 var msg u003d document.getElementById('msg').value;

48 变量数据 u003d {

49 姓名:姓名,

50 味精:味精,

51};

52 变量数据_json u003d JSON.stringify(数据);

53 ws.send(数据_json);

54 }

55 </脚本>

56 </html>

MUC_nick_route.html

版本二:根据websocket发送的昵称,通过websocket接收客户端发送的昵称:

烧瓶_websocket(MUC_nick).py

1 '''

2 基于websocket+flask的群聊即时通讯

3 设计字典client_dict u003d {}来存储{Client Name: 客户端与服务端的连接},客户端的名字由客户端WS Request协议发送和获取,

4 服务端继续接收客户端发送的信息(经过json序列化的字典)遍历存储连接信息的字典,获取客户端的连接直接转发

5'''

6 from flask import Flask, render_template, request

7 from geventwebsocket.handler import WebSocketHandler #提供WS(websocket)协议处理

8 from ventwebsocket.server import WSGIServer # websocket 服务承载

9 from geventwebsocket.websocket import WebSocket #websocket语法提示

10

11

12 应用程序 u003d 烧瓶(__name__)

13

14 客户端_dict u003d {}

15

16

17 @app.route('/websocket')

18 def websocket():

19 client_socket u003d request.environ.get('wsgi.websocket') # type:WebSocket

20 # 打印(客户端_socket)

21 客户端_name u003d 客户端_socket.receive()

22 客户端_dict[客户端_name] u003d 客户端_socket

23 # 打印(len(client_dict), client_dict)

24 而 1:

25 msg\from\cli u003d client\socket.receive()

26 # msg\from\cli\stru003djson.loads(msg\from\cli)

27 # 打印(msg\from\cli\str)

28 对于客户端_dict.values() 中的客户端:

29 次尝试:

30 client.send(msg_from_cli)

31 例外为 e:

32 继续

33

34

35 @app.route('/聊天')

36 定义聊天():

37 返回渲染_template('MUC_nick.html')

38

39

40 个 _\name__ u003du003d '__ main__':

41 # app.run('192.168.16.14',8888,debugu003dTrue)

42 http_server u003d WSGIServer(('192.168.16.14', 8888), applicationu003dapp, handler_classu003dWebSocketHandler)

43 http_server.serve_forever()

烧瓶_websocket(MUC_nick).py

MUC_nick.html

1 <!DOCTYPE html>

2 <HTML浪u003d"恩">

3 <头部>

4 <元字符集u003d"UTF-8">

5 <title>多用户无昵称聊天</title>

6 </head>

7 <身体>

8 <div idu003d"chat_room">

9 <p>输入你的昵称进入多人聊天室:<input typeu003d"text" idu003d"client_name"></input>

10 <button idu003d'login' onclicku003d"login()">登录</button>

11 </p>

12 <p idu003d'chat_msg' hiddenu003d"hidden">请输入聊天内容:<input typeu003d"text" idu003d"msg">

13 <button idu003d"send" onclicku003d"send()">发送</button>

14 </p>

15 <div idu003d"chat_content" ></div>

16 </div>

17 </正文>

18 <脚本类型u003d"应用程序/javascript">

19 var ws u003d new WebSocket('ws://192.168.16.14:8888/websocket');

20 变量名称 u003d 空;

21

22 //发送本地昵称到服务器

23 函数登录() {

24 document.getElementById('login').setAttribute('hidden', 'hidden');

25 document.getElementById('client_name').setAttribute('disabled', 'disabled');

26 document.getElementById('chat_msg').removeAttribute('hidden');

27 document.getElementById('chat_content').removeAttribute('hidden');

28 名称 u003d document.getElementById('client_name').value;

29 ws.send(姓名);

30 };

31

32

33 //监听来自服务器的消息(json数据)

34 ws.onmessage u003d 函数(消息事件){

35 //console.log(MessageEvent);

36 //console.log(MessageEvent.data);

37 var 内容_str u003d JSON.parse(MessageEvent.data);

38 var time u003d new Date();

39 var t u003d time.toLocaleTimeString();

40 var p u003d document.createElement("p");

41 p.innerText u003d 内容_str.name + "(" + t + "):" + 内容_str.msg;

42 document.getElementById('chat_content').appendChild(p);

43};

44

45

46 //聊天消息发送(json数据)

47 函数发送(){

48 var msg u003d document.getElementById('msg').value;

49 变量数据 u003d {

50 姓名:姓名,

51 味精:味精

52};

53 变量数据_json u003d JSON.stringify(数据);

54 ws.send(数据_json);

55 }

56 </脚本>

57 </html>

MUC_nick.html

(3)基于websocket+Flash的私聊即时通讯

烧瓶_websocket(私人_chat).py

1 '''

2 基于websocket+flask 私聊即时通讯

3 设计字典client_dict u003d {}来存储{Client Name: 客户端与服务端的连接},通过动态路由参数获取客户端名称,

4 服务端通过客户端发送的信息(通过json序列化字典中目标客户端的名称),获取存储字典中目标客户端的连接,直接转发

5'''

6 from flask import Flask, render_template, request

7 from geventwebsocket.handler import WebSocketHandler #提供WS(websocket)协议处理

8 from ventwebsocket.server import WSGIServer # websocket 服务承载

9 from geventwebsocket.websocket import WebSocket #websocket语法提示

10 导入json

11

12 应用程序 u003d 烧瓶(__name__)

13

14 客户端_dict u003d {}

15

16

17 @app.route('/websocket/<client_name>') # 通过动态路由参数获取昵称,必须在视图函数中定义同名的形参

18 def websocket(client_name):

19 client_socket u003d request.environ.get('wsgi.websocket') # type:WebSocket

20 客户端_dict[客户端_name] u003d 客户端_socket

21 如果客户端_socket:

22 而 1:

23 msg\from\cli u003d client\socket.receive()

24 to_client u003d json.loads(msg_from_cli).get('to_client')

25 客户端 u003d 客户端_dict.get(to_client)

26 次尝试:

27 client.send(msg_from_cli)

28 例外为 e:

29 继续

30

31

32 @app.route('/聊天')

33 定义聊天():

34 返回渲染_template('Private_chat.html')

35

36

37 如果 __name__ u003du003d '__main__':

38 http_server u003d WSGIServer(('192.168.16.14', 8888), applicationu003dapp, handler_classu003dWebSocketHandler)

39 http_server.serve_forever()

烧瓶_websocket(私人_chat).py

私人_chat.html

1 <!DOCTYPE html>

2 <HTML浪u003d"恩">

3 <头部>

4 <元字符集u003d"UTF-8">

5 <title>单人聊天室</title>

6

7 </head>

8 <正文>

9 <div idu003d"聊天\房间">

10 <p>输入昵称进入单人聊天室:<input typeu003d"text" idu003d"client_name"></input>

11 <button idu003d'login' onclicku003d"login()">登录</button>

12 </p>

13 <p hidden idu003d"client_recv">收件人:<input typeu003d"text" idu003d"to_client"></p>

14 <p idu003d'chat_msg' hiddenu003d"hidden">请输入聊天内容:<input typeu003d"text" idu003d"msg">

15

16 <button idu003d"send" onclicku003d"send()">发送</button>

17 </p>

18 <div idu003d"chat_content" hiddenu003d"hidden"></div>

19 </div>

20 </正文>

21 <脚本类型u003d"应用程序/javascript">

22 变量 ws u003d 空;

23 变量名称u003d空;

24

25 函数登录(){

26 document.getElementById('login').setAttribute('hidden', 'hidden');

27 document.getElementById('client_name').setAttribute('disabled', 'disabled');

28 document.getElementById('chat_msg').removeAttribute('hidden');

29 document.getElementById('chat_content').removeAttribute('hidden');

30 document.getElementById('client_recv').removeAttribute('hidden');

31

32 name u003d document.getElementById('client_name').value;

33 //WS实例化

34 ws u003d new WebSocket('ws://192.168.16.14:8888/websocket/' + 名称);

35

36 //监听来自服务器的消息(json数据)

37 ws.onmessage u003d 函数(消息事件){

38 //console.log(MessageEvent);

39 //console.log(MessageEvent.data);

40 var content_str u003d JSON.parse(MessageEvent.data);

41 var time u003d new Date();

42 var t u003d time.toLocaleTimeString();

43 var p u003d document.createElement("p");

44 p.innerText u003d 内容_str.name + "(" + t + "):" + 内容_str.msg;

45 document.getElementById('chat_content').appendChild(p);

46 };

47 };

48

49

50 //聊天消息发送(json数据)

51 函数发送() {

52 var msg u003d document.getElementById('msg').value;

53 var to_clientu003ddocument.getElementById('to_client').value;

54 变量数据 u003d {

55 姓名:姓名,

56 味精:味精,

57 到\客户端:到\客户端

58};

59

60 var data_json u003d JSON.stringify(data);

61 ws.send(数据_json);

62

63

64 var time u003d new Date();

65 var t u003d time.toLocaleTimeString();

66 var p u003d document.createElement("p");

67 p.innerText u003d name + "(" + t + "):" + msg;

68 document.getElementById('chat_content').appendChild(p);

69

70

71

72

73

74 }

75 </脚本>

76 </html>

私人_chat.html

实际项目后台代码:

#! /usr/bin/python2

#! -*- 编码:utf-8 -*-

从烧瓶进口烧瓶,请求

从发泄进口猴子

从 vent.pywsgi 导入 WSGIServer

从 geventwebsocket.handler 导入 WebSocketHandler

进口时间

导入 json

导入系统

导入回溯

导入日志

从 Interactive WithDatabase.interactive_with\database 导入 Get_first_record\from_database

从 pub.const_redis 导入 SYSTEM_KEY_NAME

从 MEO_DB 导入 redisLifecycle

monkey.patch_all() #支持异步请求

应用程序 u003d 烧瓶(__name__)

app.config.update(

调试u003d真

)

记录器 u003d logging.getLogger('eb_meo')

@app.route("/conn_vnfm")

定义 ws_app():

用户_socket u003d request.environ.get("wsgi.websocket")

sys_id u003d 用户_socket.receive()

subsDb u003d Get_first_record_from_database('Alarm_subscription', system_idu003dsys_id)

尝试:

如果 subsDb:

SrcType u003d subsDb.sub_type

当真:

如果 redisLifecycle.get(SYSTEM_KEY_NAME.HeartBeat + SrcType.lower() + '_' + sys_id):

用户_socket.send(json.dumps({sys_id:True}))

其他:

用户_socket.send(json.dumps({sys_id:False}))

time.sleep(subsDb.heartbeat)

其他:

用户_socket.send(json.dumps({sys_id:False}))

除了:

logger.debug(sys.exc_info())

logger.debug(traceback.format_exc())

返回 ''

服务端关闭前必须有接收阻塞,否则服务端和客户端都会因为死循环而崩溃

websocket的原理:客户端发送消息请求,服务器回复数据[如果客户端不发送消息,则循环不会阻塞,即死循环]

如果 __name__ u003du003d '__main__':

http_servu003dWSGIServer(("0.0.0.0",int(sys.argv[1])),app,handler_classu003dWebSocketHandler)

http_serv.serve_forever()

实际项目前端处理:

{% 块脚本 %}

{{超级()}}

<script typeu003d"text/javascript" srcu003d"{{url_for('static',filename u003d 'js/system.js')}}"></script>

<脚本>

//门禁系统连接状态持续监控功能

var web_socket_msg u003d {{extraData|tojson}}

控制台日志(网络_socket_msg)

var vnfms u003d {{resData.vnfms|tojson}}

函数 con_svr(vnfm_id){

// 协议是ws,支持http、wws和HTTPS

让 ws u003d new WebSocket('ws://' + web_socket_msg.ip + ':' + 字符串(web_socket_msg.port) + '/conn_vnfm')

ws.onopen u003d 函数(参数){

console.log(vnfm_id + '连接成功')

ws.send(vnfm_id)

}

ws.onmessage u003d 函数 (e) {

console.log(vnfm_id + '收到服务器响应', e.data)

var res u003d JSON.parse(e.data)

if (res[vnfm_id]){

$('#status-' + vnfm_id).addClass('glyphicon-ok-sign').css('color','#5CCBB1')

}其他{

$('#status-' + vnfm_id).removeClass('glyphicon-ok-sign').css('color','#E54545')

}

}

}

for (let vnfm of vnfms){

con_svr(vnfm.vnfm_id)

}

</脚本>

{% 端块 %}

点击阅读全文
Logo

学AI,认准AI Studio!GPU算力,限时免费领,邀请好友解锁更多惊喜福利 >>>

更多推荐