Socket:
FTP - 文件服务
Django
Flask
Http - TCP:
1.一次请求 一次响应 断开
2.客户端永远处于主动状态
3.服务器永远处于被动状态
4.Http无状态 - 在服务器不保存客户端的信息
5.服务器无法主动找到客户端
1.轮询
客户端向服务器不断发起类似Http请求
服务器不断的响应客户端
带上你的身份牌 - 服务器校验身份
大爷去找你的消息 - 服务器获取你应该拿到数据
if:拿到数据
else:拿不到数据 - 再次发起请求询问服务器消息
劣势:
1.双端资源浪费
2.带宽资源占用
3.不能保证数据实时性
上个世纪90年代 - 本世纪初:
24bps == 4-6KB
CPU == 800MHZ
内存 == 256MB
QQ -- ICQ
2.长轮询
1.客户端向服务器发起一个请求
2.服务器保持这个请求 不返回不响应
3.一定时间之后,服务器抛弃 or 返回
4.客户端收到请求 立即再次发起保持
你去传达室,大爷款待你喝茶,
喝茶等消息(保持)
上厕所(断开)
再次回去喝茶等消息(保持)
劣势:
1.服务器资源浪费
2.不能保证数据实时性
优势:
1.节省客户端资源
2.保证数据有效
当时的环境:本世纪初 - 目前
128bps == 20-30KB
Cpu == 1.4GHZ 奔腾4
内存 == 512MB
3.长连接
永久保持连接
1.你和大爷之间装了一台电话分机
2.你派人告诉大爷你的分机号码
3.大爷拨通分机
4.你告诉大爷,有消息说句话,我派人去拿
5.你和大爷同时开启了闭音
劣势:
1.服务器CPU要求较高
优势:
1.节省大量资源
2.数据实时有效性
3.带宽几乎不占用
现在的环境:
100mps == 百兆光纤 == 5MB/s || 2KB
CPU == 16核32线程 i9 3.2GHZ
内存 == 16GB
WebSocket协议:ws协议 ws://127.0.0.1 javascript封装客户端 http协议 http://127.0.0.1
三方:geventWebsocket Flask
Web框架 :用来进行Http请求的处理 (握手)
单聊:
收发快递模型:
寄件人:user1 from_user
收件人:user2 to_user
包裹
user2:
寄件人是user1 打开包裹 - 被骂了
骂回去:
寄件人:user2
收件人:user1
包裹
user1:
寄件人是user2 打开包裹 - 骂回来了
对骂吧:
寄件人:user1
收件人:user2
包裹
单聊Python
import json from geventwebsocket.handler import WebSocketHandler from gevent.pywsgi import WSGIServer from geventwebsocket.websocket import WebSocket from geventwebsocket.exceptions import WebSocketError from flask import Flask,render_template,request app = Flask(__name__) # user_socket_list = [] user_socket_dict = {} @app.route("/my_app") def my_app(): return render_template("my_app.html") @app.route("/my_ws/<username>") def my_ws(username): user_socket = request.environ.get("wsgi.websocket") # type:WebSocket user_socket_dict[username] = user_socket print(len(user_socket_dict),user_socket_dict) while 1: try: msg = user_socket.receive() # 阻塞等待消息数据 print(msg,type(msg)) msg_dict = json.loads(msg) # msg = {from_user:alexDSB,to_user:YWB,messge:"dsb"} to_user = msg_dict.get("to_user") to_user_socket = user_socket_dict.get(to_user) to_user_socket.send(msg) # user_socket_dict.get(msg.get(to_user) == "YWB").send(msg) except WebSocketError: user_socket_dict.pop(username) return "good bye" if __name__ == '__main__': # app.run() http_serv = WSGIServer(("0.0.0.0",9527),app,handler_class=WebSocketHandler) http_serv.serve_forever()
单聊 HTML <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 你的名字:<input type="text" id="nickname"> <button onclick="open_chat()">登录聊天室</button> <p>发送至<input type="text" id="to_user"></p> 消息<input type="text" id="message"> <button onclick="send_message()">发送</button> <div id="chat_list"> </div> </body> <script type="application/javascript"> var ws = null; function open_chat() { var nickname = document.getElementById("nickname").value; ws = new WebSocket("ws://192.168.14.200:9527/my_ws/" + nickname); ws.onopen = function () { alert(nickname + "!欢迎登录对骂平台!"); }; ws.onmessage = function (eventMessage) { // document.getElementById("chat_list").innerHTML += "<p>" + eventMessage.data + "</p>"; console.log(eventMessage.data); var chat = JSON.parse(eventMessage.data); var p = document.createElement("p"); p.style.cssText = " 250px;text-align: left"; p.innerText = chat.from_user + "->" + chat.message; document.getElementById("chat_list").appendChild(p); }; ws.onclose = function () { //断开重连机制 console.log("连接断开了完全懵逼了"); }; } function send_message() { var message = document.getElementById("message").value; var from_user = document.getElementById("nickname").value; var to_user = document.getElementById("to_user").value; var send_str = { from_user: from_user, to_user: to_user, message: message }; ws.send(JSON.stringify(send_str)); var p = document.createElement("p"); p.style.cssText = " 250px;text-align: right"; p.innerText = send_str.message + "<-我"; document.getElementById("chat_list").appendChild(p); } </script> </html>