WebSocket介绍

- 菜鸟教程详解连接

- 下载:pip install gevent-websocket

- WebSocket 是一种协议;是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议;

  1. WebSocket 使得客户端和服务器之间的数据交换变得更加简单,
  2. 允许服务端主动向客户端推送数据。
  3.  
  4. WebSocket API 中,
  5. 浏览器和服务器只需要完成一次握手,
  6. 两者之间就直接可以创建持久性的连接,并进行双向数据传输。

- 轮询:

  1. 是在特定的的时间间隔(如每1秒),
  2. 由浏览器对服务器发出HTTP请求,
  3. 然后由服务器返回最新的数据给客户端的浏览器。
  4.  
  5. 传统轮询的缺点:
  6. 浪费资源,
  7. 服务器,客户端压力大

- 长轮询:

  1. 客户端向服务器发送Ajax请求,服务器接到请求后hold住连接,
  2. 直到有新消息才返回响应信息并关闭连接,
  3. 客户端处理完响应信息后再向服务器发送新的请求。
  4.  
  5. 优点:在无消息的情况下不会频繁的请求,耗费资源小。
  6. 缺点:服务器hold连接会消耗资源,返回数据顺序无保证,难于管理维护。
  7. 实例:WebQQHi网页版、Facebook IM

- WebScoket:

  1. 浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,
  2. 连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。
  3.  
  4. 当你获取 Web Socket 连接后,
  5. 你可以通过 send() 方法来向服务器发送数据,
  6. 并通过 onmessage 事件来接收服务器返回的数据。

WebSocket+Flask开启一个WebSocket服务

- 示例:

  1. from flask import Flask, request
  2. from geventwebsocket.handler import WebSocketHandler # 开启WebSocket协议的服务
  3. from gevent.pywsgi import WSGIServer # WSGI 支持多线程的 socket
  4. from geventwebsocket.websocket import WebSocket
  5.  
  6. app = Flask(__name__)
  7. @app.route("/ws")
  8. def ws():
  9. # print(request.environ) # 打印原始的 request
  10. # print(request.environ.get("wsgi.websocket")) # 获取ws对象
  11. ws = request.environ.get("wsgi.websocket") # type: WebSocket
  12. data = ws.receive()
  13. print(data)
  14. ws.send("发送消息给前端")
  15.  
  16. if __name__ == '__main__':
  17. # 开启服务
  18. http_serv = WSGIServer(("0.0.0.0", 5000), app, handler_class=WebSocketHandler)
  19. http_serv.serve_forever()

  - 前端:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="x-ua-compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>Title</title>
  8. <body>
  9. <script>
  10. var ws = new WebSocket("ws://127.0.0.1:5000/we/" + username);
  11. ws.send("发送给客户端");
  12. ws.onmessage = function (data) {
  13. console.log(data.data);
  14. }
  15. </script>
  16. </body>
  17. </html>

群聊小Demo

- 视图:

  1. import json
  2.  
  3. from flask import Flask, request, render_template
  4. from geventwebsocket.handler import WebSocketHandler
  5. from gevent.pywsgi import WSGIServer
  6. from geventwebsocket.websocket import WebSocket
  7.  
  8. app = Flask(__name__)
  9. user_socket_list = []
  10.  
  11. @app.route("/ws")
  12. def ws():
  13. # print(request.environ.get("wsgi.websocket"))
  14. user_web_socket = request.environ.get("wsgi.websocket") # type: WebSocket
  15. user_socket_list.append(user_web_socket)
  16. while 1:
  17. try:
  18. data = user_web_socket.receive()
  19. print(data)
  20. for user_socket in user_socket_list:
  21. if user_web_socket != user_socket:
  22. user_socket.send(data)
  23. except:
  24. user_socket_list.remove(user_web_socket)
  25.  
  26. @app.route("/chat")
  27. def chat():
  28. return render_template("ws.html")
  29.  
  30. if __name__ == '__main__':
  31. http_serv = WSGIServer(("0.0.0.0", 5000), app, handler_class=WebSocketHandler)
  32. http_serv.serve_forever()

- 前端:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="x-ua-compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>Title</title>
  8. <body>
  9. <div>
  10. <p>发送消息:<input type="text" id="chat">
  11. <button onclick="send_msg()">发送</button>
  12. </p>
  13. </div>
  14. <div id="msg">
  15.  
  16. </div>
  17. <script>
  18. var ws = new WebSocket("ws://127.0.0.1:5000/we");
  19.  
  20. ws.onmessage = function (data) {
  21. let p_tag = document.createElement("p");
  22. p_tag.innerText = data.data;
  23. document.getElementById("msg").appendChild(p_tag);
  24. };
  25. function send_msg() {
  26. var msg = document.getElementById("chat").value;
  27. ws.send(msg);
  28. }
  29. </script>
  30. </body>
  31. </html>

私聊小Demo

- 视图:

  1. import json
  2. from flask import Flask, render_template, request
  3. from geventwebsocket.handler import WebSocketHandler # 开启WebSocket协议的服务
  4. from gevent.pywsgi import WSGIServer # WSGI 支持多线程的 socket
  5. from geventwebsocket.websocket import WebSocket
  6.  
  7. app = Flask(__name__)
  8. """
  9. 实现单人聊天原理:
  10. 1,获取不同用户的用户名
  11. 1.1 利用字典的形式,用户名为key
  12. 2,获取指定发送到某用户的用户名
  13. 3,获取数据
  14. """
  15.  
  16. web_socket_dict = {}
  17.  
  18. @app.route("/we/<username>")
  19. def we(username):
  20. # print(request.environ) # 打印原始的 request
  21. # print(request.environ.get("wsgi.websocket")) # 获取ws对象
  22. ws = request.environ.get("wsgi.websocket") # type: WebSocket
  23. web_socket_dict[username] = ws
  24. print(web_socket_dict)
  25. while 1:
  26. try:
  27. data_dict = ws.receive() # 等待接受消息
  28. data = json.loads(data_dict)
  29. to_user = data.get("to_user")
  30. chat = data.get("chat")
  31. print(to_user, chat)
  32. to_from_ws = web_socket_dict.get(to_user)
  33. msg_data = {"from_user": username, "msg": chat}
  34. to_from_ws.send(json.dumps(msg_data))
  35. except:
  36. pass
  37. # ws.send("哼!") # 接受到消息后,向前端发送消息
  38.  
  39. @app.route("/chat")
  40. def chat():
  41. return render_template("chat.html")
  42.  
  43. if __name__ == '__main__':
  44. http_serv = WSGIServer(("0.0.0.0", 5000), app, handler_class=WebSocketHandler)
  45. http_serv.serve_forever()

- 前端:

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="x-ua-compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1">
  7. <title>Title</title>
  8. <body>
  9. <div>
  10. <p>请注册您的用户名:<input type="text" id="username"></p>
  11. <p>注册到服务器
  12. <button onclick="send_username()">提交</button>
  13. </p>
  14. <p>请输入您要发送给谁:<input type="text" id="to_user"></p>
  15. <p>请输入您想发送的内容:<input type="text" id="chat"></p>
  16. <p>
  17. <button onclick="send_chat()">提交</button>
  18. </p>
  19. </div>
  20. <div id="msg"></div>
  21. <script>
  22. var ws = null;
  23.  
  24. function send_username() {
  25. let username = document.getElementById("username").value;
  26. ws = new WebSocket("ws://127.0.0.1:5000/we/" + username);
  27. ws.onmessage = function (data) {
  28. console.log(data.data);
  29. let msg_data = JSON.parse(data.data);
  30. let ptag = document.createElement("p");
  31. ptag.innerText = msg_data.from_user + " : " + msg_data.msg;
  32. document.getElementById("msg").appendChild(ptag);
  33. }
  34. }
  35.  
  36. function send_chat() {
  37. let to_user = document.getElementById("to_user").value;
  38. let chat = document.getElementById("chat").value;
  39. let data = {to_user: to_user, chat: chat};
  40. ws.send(JSON.stringify(data));
  41. }
  42. </script>
  43. </body>
  44. </html>

WebSocket 笔记的更多相关文章

  1. 学习WebSocket笔记

    由于HTTP协议是无状态的,服务器只会响应来自客户端的请求,但是它与客户端之间不具备持续连接. 当用户在浏览器上进行操作时,可以请求服务器上的api:但是反过来不可以:服务端发生了一件事,无法将这个事 ...

  2. websocket笔记

    本文为原创,转载请注明出处: cnzt       文章:cnzt-p http://www.cnblogs.com/zt-blog/p/6742746.html websocket -- 双向通信网 ...

  3. Spring 中使用 WebSocket 笔记

    编写 WebSocket 消息处理类,比较简单的方式就是直接继承AbstractWebSocketHandler,并覆写其中的处理方法,下面为一个简单的 demo public class WebSo ...

  4. 最新 .NET Core 中 WebSocket的使用 在Asp.Net MVC 中 WebSocket的使用 .NET Core 中 SignalR的使用

    ASP.NET MVC 中使用WebSocket 笔记 1.采用控制器的方法 这个只写建立链接的方法的核心方法 1.1 踩坑 网上都是直接 传个异步方法 直接接受链接 自己尝试了好多次链接是打开的,到 ...

  5. WebSocket学习笔记IE,IOS,Android等设备的兼容性问

    WebSocket学习笔记IE,IOS,Android等设备的兼容性问 一.背景 公司最近准备将一套产品放到Andriod和IOS上面去,为了统一应用的开发方式,决定用各平台APP嵌套一个HTML5浏 ...

  6. WebSocket学习笔记——无痛入门

    WebSocket学习笔记——无痛入门 标签: websocket 2014-04-09 22:05 4987人阅读 评论(1) 收藏 举报  分类: 物联网学习笔记(37)  版权声明:本文为博主原 ...

  7. Netty学习笔记(六) 简单的聊天室功能之WebSocket客户端开发实例

    在之前的Netty相关学习笔记中,学习了如何去实现聊天室的服务段,这里我们来实现聊天室的客户端,聊天室的客户端使用的是Html5和WebSocket实现,下面我们继续学习. 创建客户端 接着第五个笔记 ...

  8. SpringBoot学习笔记(11):使用WebSocket构建交互式Web应用程序

    SpringBoot学习笔记(11):使用WebSocket构建交互式Web应用程序 快速开始 本指南将引导您完成创建“hello world”应用程序的过程,该应用程序在浏览器和服务器之间来回发送消 ...

  9. WebSocket 学习笔记

    WebSocket 学习笔记 来自我的博客 因为项目原因需要用到双工通信,所以比较详细的学习了一下浏览器端支持的 WebSocket. 并记录一些遇到的问题. 简介 WebSocket 一般是指浏览器 ...

随机推荐

  1. 虚拟集群LVS及DR模式搭建笔记

    LVS(虚拟集群Linux Virtual Server) LVS-NAT:地址转换,数据包来回都要经过NAT转换,所以Director Server(即LVS服务器)将成为系统瓶颈.使用NAT模式将 ...

  2. 在WIN7、WIN10操作系统用WebDAV映射网络驱动器需要的操作

    如果WebDAV不是https的,win7默认是添加不上的,需要修改注册表使得WIN7同时支持http和https,默认只支持https,然后重启服务 某一服务器,配置好了WebDAV.用苹果电脑作客 ...

  3. GraphicsMagick java.io.FileNotFoundException: gm 错误解决办法

    GraphicsMagick java.io.FileNotFoundException: gm 解决办法, 方法一: ProcessStarter.setGlobalSearchPath(" ...

  4. PhpStorm Live Template加PHP短语法Short Open Tags打造原生模板

    关于Php要不要使用模板一直被大家讨论,支持的说使用模板更简洁,易与前端project师交流.反对的说Php本身就支持内嵌语法,不是必需再用个模板,减少性能. 事实上使用Php的短语法.直接嵌入也不是 ...

  5. Android Jni 调用

    Chap1:JNI完全手册... 3 Chap2:JNI-百度百科... 11 Chap 3:javah命令帮助信息... 16 Chap 4:用javah产生一个.h文件... 17 Chap5:j ...

  6. python 统计文件top IP

    lines = ''' 1.2.2.3 1.21.29.19.... ''' cnt = {} for line in lines.split(): if line not in cnt: cnt[l ...

  7. springboot 静态方法注入bean、使用@value给static变量赋值

    首先新建你的方法类:DemoUtil 头部加注解:@Component @Component public class DemoUtil { } 新增静态变量: static DemoService ...

  8. react --- 路由传参的几种方式

    1.params 优势 : 刷新地址栏,参数依然存在缺点:只能传字符串,并且,如果传的值太多的话,url会变得长而丑陋. 2.query 优势:传参优雅,传递参数可传对象:缺点:刷新地址栏,参数丢失 ...

  9. Android 如何打造Android自定义的下拉列表框控件

    一.概述 Android中的有个原生的下拉列表控件Spinner,但是这个控件有时候不符合我们自己的要求, 比如有时候我们需要类似windows 或者web网页中常见的那种下拉列表控件,类似下图这样的 ...

  10. MVC5 + EF6 入门完整教程(转载)--01

    MVC5 + EF6 入门完整教程   第0课 从0开始 ASP.NET MVC开发模式和传统的WebForm开发模式相比,增加了很多"约定". 直接讲这些 "约定&qu ...