热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

flask4+websocket

2019.7.15Http协议Http:超文本传输协议传输:SocketTCP3次握手断开四次挥手无状态请求连接TCP3次握手发起一次请求-一次响应-连接就断开了ht

2019.7.15

Http协议

Http: 超文本传输协议 传输:Socket TCP 3次握手 断开 四次挥手

无状态请求连接

TCP 3次握手 发起一次请求 - 一次响应 - 连接就断开了

http://www.baidu.com 长时间无请求时,不占用任何资源

劣势:

无状态 -
比如 :
客户端1向服务器发起请求 - 服务器确认客户端1的身份 - 处理 - 响应 - 断开
客户端1向服务器发起请求 - 服务器确认客户端1的身份 - 处理 - 响应 - 断开

服务器主动向客户端推送消息

WeChat - 微信
‘你’发送一条微信 - 给服务器 - ‘你好!’ - 服务器收到消息 - 服务器寻找 ‘我’ - 对着我的连接 (客户端) - 发送 你好!WeChatPay
AliPay

1.轮询 对客户端 以及服务器要求最高

客户端轮询 - 由客户端向服务器发起请求 每秒10次左右(QPS 每秒发起请求的次数限制)

场景模拟

传达室 收发快递模型 1.大爷(接收快递) - 小二 半年之后 扔掉
2.大爷(接收快递) - 小二 -小二从宿舍跑到传达室 - 问大爷 有我快递吗?-大爷回答:你丫谁呀? 我是大三小二- 我知道了,你找我什么事儿? - 小二 : 有我快递吗? - 大爷:我给你找找,没找着,你回去把,一会过来- 小二 :大爷再见 再见 再见 再见- 小二到宿舍想起来快递没拿- 又去传达室取快递(重复上面的过程)- 很多个小二 同事问大爷快递
知道很久以后
- 小二 我是大三的小二
- 我知道了,你汇总啊我什么事儿?
- 小二 : 有我快递吗?
- 大爷: 我这儿真有你的快递
- 小二 拿走快递,飞奔二区
- 小二:大爷再见 再见 再见 再见

​ 小资源访问时 优势很明显 - 因为客户端较少

2.长轮询

服务器长轮询 - 服务器不响应客户端而是将连接暂时保持住 5 秒之后 没有消息,响应客户端

一定时间之后 5s之后 断开连接, 客户端重新发起请求

情景模拟:

大爷(接收快递) - 小二
传达室装修了 - 建立了一个茶室 - 服务升级了
小二到传达室 - 问大爷有我快递吗?
- 大爷: 你丫谁呀?
- 小二:我是大三小二
- 大爷:我知道了,你找我什么事儿?
- 小二: 有我快递吗?
- 大爷:进屋做做,屋里有差,我给你找找快递
- 小二喝茶中。。。。。。
- 大爷:你多等会
- 小二喝茶中。。。。。。
- 大爷:你多等会
- 小二喝茶中。。。。。。
- 小二: 大爷,我去趟厕所
- 断开
- 小二上完厕所,不对呀,我又不是去喝茶的
- 小二来到传达室 loop小二到传达室 - 问大爷有我快递吗?
- 大爷: 你丫谁呀?
- 小二:我是大三小二
- 大爷:我知道了,你找我什么事儿?
- 小二: 有我快递吗?
- 大爷:进屋做做,屋里有差,我给你找找快递
- 小二喝茶中。。。。。。
- 大爷说 找到了,你的快递
- 小二拿着快递美美的回去了 断开了

优势:

小二不用那么累了 客户端不用大量QPS

劣势:

传达室的茶室空间 严重浪费服务器资源

大爷学会了影分身 开启多线程服务客户端

3.长连接 客户端和 服务器资源 消耗没有那么严重了

连接保持 - Http 发起请求在请求中写一个协议 - WebSocket - 收到请求,自动保持此连接 - 永久不断开, 除非主动断开 - 可以通过此连接主动找到客户端

场景模拟

大爷(接收快递) - 小二
传达室进入信息化时代,装电话了 2万台电话
小二到传达室 - 问大爷有我快递吗?
- 大爷: 你丫谁呀?
- 小二:我是大三小二
- 大爷:我知道了,你找我什么事儿?
- 小二: 有我快递吗?
- 大爷:你把电话号码留下,回去等我电话,接了之后别挂
- 小二回到宿舍证号听见大爷来电话了
- 小二接电话 , 对面,我是你大爷,电话别挂,随时听着,有快递就过来取
- 保持通话

优势:数据实时性

劣势:服务器和客户端需要一个线程来等待消息

玩游戏:一个服务器有资源限制,所以分区,很多个服务器

服务器 完成 IO多路复用

2 . GeventWebsocket + Flask

Web (Http) + Socket (连接保持)

Flask中运行WebSocket - GeventWebsocket

wsgi?

wsgi ---> envir ---> view

wsgi ---> http ---> envir ---> view

wsgi ---> websockethandler ---> envir ---> view

websockethandler 监听了 请求头中的?

ws environ 和 headers

ws请求 environ 原始信息

{&#39;GATEWAY_INTERFACE&#39;: &#39;CGI/1.1&#39;, &#39;SERVER_SOFTWARE&#39;: &#39;gevent/1.4 Python/3.6&#39;, &#39;SCRIPT_NAME&#39;: &#39;&#39;, &#39;wsgi.version&#39;: (1, 0), &#39;wsgi.multithread&#39;: False, &#39;wsgi.multiprocess&#39;: False, &#39;wsgi.run_once&#39;: False, &#39;wsgi.url_scheme&#39;: &#39;http&#39;, &#39;wsgi.errors&#39;: <_io.TextIOWrapper name&#61;&#39;&#39; mode&#61;&#39;w&#39; encoding&#61;&#39;UTF-8&#39;>, &#39;SERVER_NAME&#39;: &#39;Win7-2019WPWAAA&#39;, &#39;SERVER_PORT&#39;: &#39;9537&#39;, &#39;REQUEST_METHOD&#39;: &#39;GET&#39;, &#39;PATH_INFO&#39;: &#39;/my_socket&#39;, &#39;QUERY_STRING&#39;: &#39;&#39;, &#39;SERVER_PROTOCOL&#39;: &#39;HTTP/1.1&#39;, &#39;REMOTE_ADDR&#39;: &#39;127.0.0.1&#39;, &#39;REMOTE_PORT&#39;: &#39;50844&#39;, &#39;HTTP_HOST&#39;: &#39;127.0.0.1:9537&#39;, &#39;HTTP_CONNECTION&#39;: &#39;Upgrade&#39;, &#39;HTTP_PRAGMA&#39;: &#39;no-cache&#39;, &#39;HTTP_CACHE_CONTROL&#39;: &#39;no-cache&#39;, &#39;HTTP_USER_AGENT&#39;: &#39;Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36&#39;, &#39;HTTP_UPGRADE&#39;: &#39;websocket&#39;, &#39;HTTP_ORIGIN&#39;: &#39;http://localhost:49419&#39;, &#39;HTTP_SEC_WEBSOCKET_VERSION&#39;: &#39;13&#39;, &#39;HTTP_ACCEPT_ENCODING&#39;: &#39;gzip, deflate, br&#39;, &#39;HTTP_ACCEPT_LANGUAGE&#39;: &#39;zh-CN,zh;q&#61;0.9&#39;, &#39;HTTP_COOKIE&#39;: &#39;csrftoken&#61;5L4cgBIxsjanDPXGuTBlOk5ihhrn8LYnSppNIG4LyEclJHsC6MOC7AR9K1jbDJUO; sessionid&#61;ofv3e4j3kmwo26wrimax68wz5t56rmr3&#39;, &#39;HTTP_SEC_WEBSOCKET_KEY&#39;: &#39;KNmnx/BwHQ1R3Q&#43;DxJNRGQ&#61;&#61;&#39;, &#39;HTTP_SEC_WEBSOCKET_EXTENSIONS&#39;: &#39;permessage-deflate; client_max_window_bits&#39;, &#39;wsgi.input&#39;: , &#39;wsgi.input_terminated&#39;: True, &#39;wsgi.websocket_version&#39;: &#39;13&#39;, &#39;wsgi.websocket&#39;: , &#39;werkzeug.request&#39;: }

&#39;wsgi.websocket&#39;: ,

http environ

#{&#39;GATEWAY_INTERFACE&#39;: &#39;CGI/1.1&#39;, &#39;SERVER_SOFTWARE&#39;: &#39;gevent/1.4 Python/3.6&#39;, &#39;SCRIPT_NAME&#39;: &#39;&#39;, &#39;wsgi.version&#39;: (1, 0), &#39;wsgi.multithread&#39;: False, &#39;wsgi.multiprocess&#39;: False, &#39;wsgi.run_once&#39;: False, &#39;wsgi.url_scheme&#39;: &#39;http&#39;, &#39;wsgi.errors&#39;: <_io.TextIOWrapper name&#61;&#39;&#39; mode&#61;&#39;w&#39; encoding&#61;&#39;UTF-8&#39;>, &#39;SERVER_NAME&#39;: &#39;Win7-2019WPWAAA&#39;, &#39;SERVER_PORT&#39;: &#39;9537&#39;, &#39;REQUEST_METHOD&#39;: &#39;GET&#39;, &#39;PATH_INFO&#39;: &#39;/my_socket&#39;, &#39;QUERY_STRING&#39;: &#39;&#39;, &#39;SERVER_PROTOCOL&#39;: &#39;HTTP/1.1&#39;, &#39;REMOTE_ADDR&#39;: &#39;127.0.0.1&#39;, &#39;REMOTE_PORT&#39;: &#39;50450&#39;, &#39;HTTP_HOST&#39;: &#39;127.0.0.1:9537&#39;, &#39;HTTP_CONNECTION&#39;: &#39;keep-alive&#39;, &#39;HTTP_CACHE_CONTROL&#39;: &#39;max-age&#61;0&#39;, &#39;HTTP_UPGRADE_INSECURE_REQUESTS&#39;: &#39;1&#39;, &#39;HTTP_USER_AGENT&#39;: &#39;Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36&#39;, &#39;HTTP_ACCEPT&#39;: &#39;text/html,application/xhtml&#43;xml,application/xml;q&#61;0.9,image/webp,image/apng,*/*;q&#61;0.8,application/signed-exchange;v&#61;b3&#39;, &#39;HTTP_ACCEPT_ENCODING&#39;: &#39;gzip, deflate, br&#39;, &#39;HTTP_ACCEPT_LANGUAGE&#39;: &#39;zh-CN,zh;q&#61;0.9&#39;, &#39;HTTP_COOKIE&#39;: &#39;csrftoken&#61;5L4cgBIxsjanDPXGuTBlOk5ihhrn8LYnSppNIG4LyEclJHsC6MOC7AR9K1jbDJUO; sessionid&#61;ofv3e4j3kmwo26wrimax68wz5t56rmr3&#39;, &#39;wsgi.input&#39;: , &#39;wsgi.input_terminated&#39;: True, &#39;werkzeug.request&#39;: }

http - readers

Host: 127.0.0.1:9537
Connection: keep-alive
Cache-Control: max-age&#61;0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36
Accept: text/html,application/xhtml&#43;xml,application/xml;q&#61;0.9,image/webp,image/apng,*/*;q&#61;0.8,application/signed-exchange;v&#61;b3
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q&#61;0.9
COOKIE: csrftoken&#61;5L4cgBIxsjanDPXGuTBlOk5ihhrn8LYnSppNIG4LyEclJHsC6MOC7AR9K1jbDJUO

ws
WebSocket {url: "ws://127.0.0.1:9537/my_socket", readyState: 3, bufferedAmount: 0, onopen: null, onerror: null, …}

ws - headers

Host: 127.0.0.1:9537
Connection: Upgrade
Pragma: no-cache
Cache-Control: no-cache
User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.108 Safari/537.36
Upgrade: websocket # &#61;&#61; websocket 请求 websockethandler处理的key 握手的信息
Origin: http://localhost:49419
Sec-Websocket-Version: 13 #
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q&#61;0.9
COOKIE: csrftoken&#61;5L4cgBIxsjanDPXGuTBlOk5ihhrn8LYnSppNIG4LyEclJHsC6MOC7AR9K1jbDJUO; sessionid&#61;ofv3e4j3kmwo26wrimax68wz5t56rmr3
Sec-Websocket-Key: jiytsu3cA3JWnElexaajjA&#61;&#61; # 公钥
Sec-Websocket-Extensions: permessage-deflate; client_max_window_bits

和一个东西计算出私钥 &#xff0c; 匹配出来的值能不能建立起联系

html 代码&#xff1a;



py

# 客户端
# 服务端
# Http Flask 浏览器
# Websocket GeventWebsocket&#43;Flask 客户端Javascript&#xff08;Websocket客户端&#xff09;from flask import Flask,request,render_template
from geventwebsocket.handler import WebSocketHandler # 提供WS协议处理
from geventwebsocket.server import WSGIServer # 承载服务
from geventwebsocket.websocket import WebSocket # 语法提示app &#61; Flask(__name__)user_socket_list &#61; []&#64;app.route("/my_socket")
def my_socket():# 获取当前客户端与服务器的Socket连接user_socket &#61; request.environ.get("wsgi.websocket") # type:WebSocketif user_socket:user_socket_list.append(user_socket)print(len(user_socket_list),user_socket_list)# print(user_socket,"OK 连接已经建立好了&#xff0c;接下来发消息吧")while 1:msg &#61; user_socket.receive()print(msg)for usocket in user_socket_list:try:usocket.send(msg)except:continue# user_socket.send(msg)# print(request.headers)&#64;app.route("/gc")
def gc():return render_template("gc.html")if __name__ &#61;&#61; &#39;__main__&#39;:# app.run("0.0.0.0",9527)http_serv &#61; WSGIServer(("0.0.0.0",9527),app,handler_class&#61;WebSocketHandler)http_serv.serve_forever()

sl.html






我的昵称&#xff1a;


发送




py

# 客户端
# 服务端
# Http Flask 浏览器
# Websocket GeventWebsocket&#43;Flask 客户端Javascript&#xff08;Websocket客户端&#xff09;
import jsonfrom flask import Flask,request,render_template
from geventwebsocket.handler import WebSocketHandler # 提供WS协议处理
from geventwebsocket.server import WSGIServer # 承载服务
from geventwebsocket.websocket import WebSocket # 语法提示app &#61; Flask(__name__)# user_socket_dict &#61; {nicheng:lianjie}
user_socket_dict &#61; {}&#64;app.route("/my_socket/")
def my_socket(username):# 获取当前客户端与服务器的Socket连接user_socket &#61; request.environ.get("wsgi.websocket") # type:WebSocketif user_socket:user_socket_dict[username] &#61; user_socketprint(len(user_socket_dict),user_socket_dict)# print(user_socket,"OK 连接已经建立好了&#xff0c;接下来发消息吧")while 1:msg &#61; user_socket.receive()msg_dict &#61; json.loads(msg)# msg &#61; user_socket.receive()to_user_nick &#61; msg_dict.get("to_user")print(to_user_nick)to_user_socket &#61; user_socket_dict.get(to_user_nick)to_user_socket.send(msg)&#64;app.route("/sl")
def sl():return render_template("sl.html")if __name__ &#61;&#61; &#39;__main__&#39;:# app.run("0.0.0.0",9527)http_serv &#61; WSGIServer(("0.0.0.0",9527),app,handler_class&#61;WebSocketHandler)http_serv.serve_forever()

错误 1 net::ERR_CONNECTION_REFUSED

ws &#61; new WebSocket(&#39;ws://192.168.16.40:9537/gc&#39;);
WebSocket is already in CLOSING or CLOSED state.

错误 2

ws &#61; new WebSocket(&#39;ws://192.168.16.40:9537/my_socket&#39;);

WebSocket {url: "ws://192.168.16.40:9537/my_socket", readyState: 0, bufferedAmount: 0, onopen: null, onerror: null, …}
VM65:1 WebSocket connection to &#39;ws://192.168.16.40:9537/my_socket&#39; failed: Error in connection establishment:

发错了地址&#xff0c;发到了 40端口&#xff0c;老师的端口了

gc.html









老 gc .html




我的昵称&#xff1a;


ws.onmessage &#61; function (eventMessage) {
eventMessage : 和request似的&#xff1f;

函数作用&#xff1f;

function send_msg() {var content &#61; document.getElementById("content").value;ws.send(content);}

Uncaught ReferenceError: send_msg is not defined

var ws &#61; new WebSocket("ws://192.168.16.90:9537/my_socket");// 监听电话ws.onmessage &#61; function (eventMessage) {console.log(eventMessage.data);var p &#61; document.createElement("p");p.innerText &#61; eventMessage.data;document.getElementById("chat_list").appendChild(p);};

没有发送函数也可以实现增加信息&#xff0c;只不过服务器端不显示


并不是&#xff0c;好像是没有数据了&#xff1f; 这样 数据是发过去又发回来的&#xff0c;为什么不直接使用呢

for usocket in user_socket_list:
try:
usocket.send(msg) #前端接收的eventmesaage.data 就是这个msg
# print(&#39;haole&#39;)
except:
continue

也不知道改动的什么地方&#xff0c;莫名其妙就好了

因为看不出那里有错&#xff0c;照抄的老师的&#xff0c;还把前端后端都换成老师的&#xff0c;然后去看视频&#xff0c;发现老师是没放在群聊的文件夹里&#xff0c;所以就把他提了出来&#xff0c;就好使了&#xff0c;然后再去运行之前的&#xff0c;也好使了。不知道错误在哪&#xff1f;还会出错的&#xff0c;对吗&#xff1f;

告诉你&#xff1a;

不是 from flask import Flask,request,render_template

而是 import json 脑子怎么长的&#xff1f;奇特&#xff01;

前端写 JSON 大写 额

ws.send(JSON.stringify(sendStr));

laoqunliao




我的昵称&#xff1a;

str_obj &#61; JSON.parse(eventMessage.data);
p.innerText &#61; str_obj.from_user &#43;" : "&#43;str_obj.chat;

显示 ----> dasf : adfas

p.innerText &#61; eventMessage.data;

显示 ----> {"from_user":"adas","chat":"ada"}

这个函数果然没大有实际作用&#xff0c;因为通过直接打开html , 错误因为没法识别 tmplates 吗&#xff1f;

# &#64;app.route("/gcs")
# def gc():
# return render_template("gcs.html")

那个make jinja 了 哪个可以被识别好像 那就可以蓝图文件夹用公有资源了把&#xff1f;&#xff01;

错误原因&#xff1f;好几次了

ws.send(JSON.stringify(sendStr));

是我没点登陆 &#xff1f; 发的是空
Uncaught TypeError: Cannot read property &#39;send&#39; of null

AttributeError: &#39;NoneType&#39; object has no attribute &#39;send&#39; # kong不能打.send

Cannot read property &#39;send&#39; of null

是因为没有用户&#xff0c;不支持离线。亮哥说。解决了&#xff0c;好似&#xff0c;但是我之前怎么可已发过去&#xff1f;也没有确认用户存在所以接收功能吧&#xff1f;

多个人聊天&#xff0c;所以需要另外一个人&#xff0c;不能自己和自己聊吧

源码讲解 &#xff1a;当http直接访问 而不是ws

错误返回&#xff1a;

null not revice()

大意&#xff1a;

websockethandler 也是 WSGI的 只不过封装了

继承的WSGIHandler 除了能够处理标准的http&#xff0c;还可以处理webserver

GUID magic_string 用来做通信协议验证的

self.environ.update ({&#39;wsgi.websocket&#39;:None}) #http还是web都有environ原始信息

self.websocket &#61; None #都给了None

只有websocket 才有http_update , http请求没有

读源码的时候各种记笔记&#xff1a; 防止忘了 #

ws登录 ws://192.168.16.90 登录 aaa sec 密钥 。。。

self.websocket &#61; Websocket(self.environ,) #夯住了 新的长连接一直保持着

http -> websocket

environ.update &#61; {&#39;&#39;} # http请求进来 没有http-upgrate 只有None , None没法receive

明天讲websocket 握手原理 和 加密 (有时间的话)

源码&#xff1a;

SUPPORTED_VERSIONS &#61; (&#39;13&#39;, &#39;8&#39;, &#39;7&#39;)
GUID &#61; "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"

self.environ.update({&#39;wsgi.websocket&#39;: None
})
self.websocket &#61; None

upgrade &#61; self.environ.get(&#39;HTTP_UPGRADE&#39;, &#39;&#39;).lower()

&#39;HTTP_UPGRADE&#39;: &#39;websocket&#39;

if upgrade &#61;&#61; &#39;websocket&#39;:connection &#61; self.environ.get(&#39;HTTP_CONNECTION&#39;, &#39;&#39;).lower() #加到了connection里面

&#39;HTTP_CONNECTION&#39;: &#39;Upgrade&#39; ws都有 这两个key

if &#39;upgrade&#39; not in connection:# This is not a websocket request, so we must not handle itself.logger.warning("Client didn&#39;t ask for a connection ""upgrade")return
else:# This is not a websocket request, so we must not handle itreturn

if self.request_version !&#61; &#39;HTTP/1.1&#39;: # websocket 默认是http/1.1 略过

&#39;HTTP_SEC_WEBSOCKET_VERSION&#39;: &#39;13&#39;, #

if self.environ.get(&#39;HTTP_SEC_WEBSOCKET_VERSION&#39;):return self.upgrade_connection()

def upgrade_connection(self):

version &#61; self.environ.get("HTTP_SEC_WEBSOCKET_VERSION")

SUPPORTED_VERSIONS &#61; (&#39;13&#39;, &#39;8&#39;, &#39;7&#39;)

为Sec-WebSocket-Accept 做准备

key &#61; self.environ.get("HTTP_SEC_WEBSOCKET_KEY", &#39;&#39;).strip()

key_len &#61; len(base64.b64decode(key))

http 请求不就是tcp请求&#xff0c;tcp请求本质上不就是socket请求&#xff0c;所以把 def upgrade_connection(self):

​ #Validate and &#39;upgrade&#39; the HTTP request to a WebSocket request. ---> self.websocket

如果Sec-WebSocket-Accept匹配对了&#xff0c;一直保持着

self.websocket &#61; WebSocket(self.environ, Stream(self), self) #创建一个新的连接 保持长连接 # 里面是init函数
self.environ.update({&#39;wsgi.websocket_version&#39;: version,&#39;wsgi.websocket&#39;: self.websocket #把连接放到wsig里了
})

class WebSocket(object):def __init__(self, environ, stream, handler): #self &#61;&#61; WSGIServer? ?WebSocketHandler

if PY3:accept &#61; base64.b64encode( #accept验证通过的字符串hashlib.sha1((key &#43; self.GUID).encode("latin-1")).digest()).decode("latin-1") #通过之后才能一直连接
else:accept &#61; base64.b64encode(hashlib.sha1(key &#43; self.GUID).digest())

headers &#61; [("Upgrade", "websocket"),("Connection", "Upgrade"),("Sec-WebSocket-Accept", accept)
]

走了这么多&#xff0c;给http请求的返回了none&#xff0c;给ws请求的返回了 websocket(不知道是什么)

程序的部分&#xff0c;为什么会错

http请求&#xff0c;源码里&#xff0c;wsgi.websocket 给的none 然后就返回了

user_socket &#61; request.environ.get("wsgi.websocket") # type:WebSocket
if user_socket:user_socket_list.append(user_socket)print(len(user_socket_list),user_socket_list)
# print(user_socket,"OK 连接已经建立好了&#xff0c;接下来发消息吧")
while 1:msg &#61; user_socket.receive() # send_msg 发过来的信息 # http请求这里是None &#xff0c;print(msg)

所以&#xff0c;AttributeError: &#39;NoneType&#39; object has no attribute &#39;receive&#39;

代码整理一下

一个发送框&#xff0c;一直发送&#xff0c;因为while了的&#xff0c;还得跳出来吗&#xff1f; .py

from flask import Flask,request,render_template
from geventwebsocket.handler import WebSocketHandler #提供WS协议
from geventwebsocket.server import WSGIServer #承载服务
from geventwebsocket.websocket import WebSocket # 语法提示app &#61; Flask(__name__)
user_socket_list &#61; [] #存放每个socket的列表&#64;app.route(&#39;/ql&#39;)
def ql():return render_template(&#39;ql1.html&#39;)&#64;app.route(&#39;/my_socket&#39;)
def my_socket():# 获取当前客户端与服务器的socket连接user_socket &#61; request.environ.get(&#39;wsgi.websocket&#39;) #type:WebSocketif user_socket:user_socket_list.append(user_socket) # 加入多个用户print(len(user_socket_list),user_socket_list) #1 []while 1 :msg &#61; user_socket.receive() # 接收前端发过来的信息print(msg)for usocket in user_socket_list:try:usocket.send(msg)except :continue #断开连接的 不影响整个群聊if __name__ &#61;&#61; &#39;__main__&#39;:http_serv &#61; WSGIServer((&#39;0.0.0.0&#39;,9527),app,handler_class&#61;WebSocketHandler)http_serv.serve_forever()

一个的前端.html



群昵称.html

我的昵称&#xff1a;

群聊昵称.py

import jsonuser_socket_dict &#61; {}&#64;app.route("/my_socket/")
def my_socket(username):# 获取当前客户端与服务器的Socket连接user_socket &#61; request.environ.get("wsgi.websocket") # type:WebSocketif user_socket:user_socket_dict[username] &#61; user_socketprint(len(user_socket_dict),user_socket_dict)# print(user_socket,"OK 连接已经建立好了&#xff0c;接下来发消息吧")while 1:# msg &#61; json.loads(user_socket.receive())msg &#61; user_socket.receive()print(msg)for usocket in user_socket_dict.values():print(usocket)try:usocket.send(msg)except:continue

私聊.html

我的昵称&#xff1a;


发送



私聊.html

app &#61; Flask(__name__)# user_socket_dict &#61; {nicheng:lianjie}
user_socket_dict &#61; {}&#64;app.route("/my_socket/")
def my_socket(username):# 获取当前客户端与服务器的Socket连接user_socket &#61; request.environ.get("wsgi.websocket") # type:WebSocketif user_socket:user_socket_dict[username] &#61; user_socket # bbbb &#61; {geventprint(len(user_socket_dict),&#39;dict&#39;,user_socket_dict)# print(user_socket,"OK 连接已经建立好了&#xff0c;接下来发消息吧")while 1:msg &#61; user_socket.receive()msg_dict &#61; json.loads(msg)# msg &#61; user_socket.receive()to_user_nick &#61; msg_dict.get("to_user") #&#39;bbbb&#39;print(&#39;toueser-nick&#39;,to_user_nick)to_user_socket &#61; user_socket_dict.get(to_user_nick) #&#39;bbbb&#39;to_user_socket.send(msg)&#64;app.route("/sl")
def sl():return render_template("sl.html")

转:https://www.cnblogs.com/Doner/p/11188172.html



推荐阅读
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • 本文介绍了RPC框架Thrift的安装环境变量配置与第一个实例,讲解了RPC的概念以及如何解决跨语言、c++客户端、web服务端、远程调用等需求。Thrift开发方便上手快,性能和稳定性也不错,适合初学者学习和使用。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了在rhel5.5操作系统下搭建网关+LAMP+postfix+dhcp的步骤和配置方法。通过配置dhcp自动分配ip、实现外网访问公司网站、内网收发邮件、内网上网以及SNAT转换等功能。详细介绍了安装dhcp和配置相关文件的步骤,并提供了相关的命令和配置示例。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 本文介绍了如何使用iptables添加非对称的NAT规则段,以实现内网穿透和端口转发的功能。通过查阅相关文章,得出了解决方案,即当匹配的端口在映射端口的区间内时,可以成功进行端口转发。详细的操作步骤和命令示例也在文章中给出。 ... [详细]
  • 本文介绍了在使用Python中的aiohttp模块模拟服务器时出现的连接失败问题,并提供了相应的解决方法。文章中详细说明了出错的代码以及相关的软件版本和环境信息,同时也提到了相关的警告信息和函数的替代方案。通过阅读本文,读者可以了解到如何解决Python连接服务器失败的问题,并对aiohttp模块有更深入的了解。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 本文介绍了在mac环境下使用nginx配置nodejs代理服务器的步骤,包括安装nginx、创建目录和文件、配置代理的域名和日志记录等。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
author-avatar
mobiledu2502861763
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有