通过python和websocket构建实时通信系统[扩展saltstack监控]

简介:

先放一个小demo~

用html5的websocket实现的聊天平台。后端用的是python bottle框架。

后期要改成监控,可能要联合saltstack做实时的监控。

像上篇博客说的那样,实时监控就那点东西,就是接收数据、显示数据 。

像下面这样:

原文地址:http://rfyiamcool.blog.51cto.com/1030776/1269232

221841208.png

WebSocket API是下一代客户端-服务器的异步通信方法。该通信取代了单个的TCP套接字,使用ws或wss协议,可用于任意的客户端和服务器程序。WebSocket目前由W3C进行标准化。WebSocket已经受到Firefox 4、Chrome 、Opera 10.70以及Safari 5等浏览器的支持。

WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。

WebSocket的优点

a)、服务器与客户端之间交换的标头信息很小,大概只有2字节;

b)、客户端与服务器都可以主动传送数据给对方;

c)、不用频率创建TCP请求及销毁请求,减少网络带宽资源的占用,同时也节省服务器资源;


1
2
3
4
5
6
7
8
9
10
11
12
建立连接的握手
当Web应用程序调用 new  WebSocket(url)接口时,Browser就开始了与地址为url的WebServer建立握手连接的过程。
1 . Browser与WebSocket服务器通过TCP三次握手建立连接,如果这个建立连接失败,那么后面的过程就不会执行,Web应用程序将收到错误消息通知。
2 . 在TCP建立连接成功后,Browser/UA通过http协议传送WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端。
3 . WebSocket服务器收到Browser/UA发送来的握手请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手连接,并给出相应的数据回复,同样回复的数据包也是采用http协议传输。
4 . Browser收到服务器回复的数据包后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,触发onopen消息,此时Web开发者就可以在此时通过send接口想服务器发送数据。否则,握手连接失败,Web应用程序会收到onerror消息,并且能知道连接失败的原因。
这个握手很像HTTP,但是实际上却不是,它允许服务器以HTTP的方式解释一部分handshake的请求,然后切换为websocket
数据传输
WebScoket协议中,数据以帧序列的形式传输。
考虑到数据安全性,客户端向服务器传输的数据帧必须进行掩码处理。服务器若接收到未经过掩码处理的数据帧,则必须主动关闭连接。
服务器向客户端传输的数据帧一定不能进行掩码处理。客户端若接收到经过掩码处理的数据帧,则必须主动关闭连接。
针对上情况,发现错误的一方可向对方发送close帧(状态码是 1002 ,表示协议错误),以关闭连接。



113832705.jpg

ws的连接状态:


1
2
3
4
5
6
GET /chat HTTP/ 1.1
Upgrade: WebSocket
Connection: Upgrade
Host:  66 .xiaorui.cc: 10000
Origin: http: //66.xiaorui.cc
Cookie: somenterCookie


简单了解下接口方法和属性:

  • readyState表示连接有四种状态:
    CONNECTING (0):表示还没建立连接;
    OPEN (1): 已经建立连接,可以进行通讯;
    CLOSING (2):通过关闭握手,正在关闭连接;
    CLOSED (3):连接已经关闭或无法打开;

  • url是代表 WebSocket 服务器的网络地址,协议通常是”ws”或“wss(加密通信)”,send 方法就是发送数据到服务器端;

  • close 方法就是关闭连接;

  • onopen连接建立,即握手成功触发的事件;

  • onmessage收到服务器消息时触发的事件;

  • onerror异常触发的事件;

  • onclose关闭连接触发的事件;


来个例子,咱们用js来搞搞

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var  wsServer =  'ws://localhost:8888/Demo' ; //服务器地址
var  websocket =  new  WebSocket(wsServer);  //创建WebSocket对象
websocket.send( "hello" ); //向服务器发送消息
alert(websocket.readyState); //查看websocket当前状态
websocket.onopen =  function  (evt) {
     //已经建立连接
};
websocket.onclose =  function  (evt) {
     //已经关闭连接
};
websocket.onmessage =  function  (evt) {
     //收到服务器消息,使用evt.data提取
};
websocket.onerror =  function  (evt) {
     //产生异常
};


我的后端代码:

python的后端实现websocket的处理,有很多方法的。

比较常见的是 gevent的websocket的方式。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from bottle  import  get , run, template
from bottle.ext.websocket  import  GeventWebSocketServer
from bottle.ext.websocket  import  websocket
import  gevent
users =  set ()
@ get ( '/' )
def index():
     return  template( 'index' )
@ get ( '/websocket' , apply=[websocket])
def chat(ws):
     users.add(ws)
     while  True:
         msg = ws.receive()
         if  msg  is  not None:
             for  in  users:
                 print type(u)
                 u.send(msg)
                 print u,msg
         else break
     users.remove(ws)
run(host= '10.10.10.66' , port= 10000 , server=GeventWebSocketServer)


后端的东西比较的简单,就是把接收到的数据,原路打回去。。。

我前端的代码

这个是连接webscoket,然后接收和发数据的js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
         $(document).ready( function () {
             if  (!window.WebSocket) {
                 if  (window.MozWebSocket) {
                     window.WebSocket = window.MozWebSocket;
                 else  {
                     $( '#messages' ).append( "<li>Your browser doesn't support WebSockets.</li>" );
                 }
             }
             ws =  new  WebSocket( 'ws://10.10.10.66:10000/websocket' );
             ws.onopen =  function (evt) {
                 $( '#messages' ).append( '<li>Connected to chat.</li>' );
             }
             ws.onmessage =  function (evt) {
                 $( '#messages' ).append( '<li>'  + evt.data +  '</li>' );
             }
             $( '#send-message' ).submit( function () {
                 ws.send($( '#name' ).val() +  ": "  + $( '#message' ).val());
                 $( '#message' ).val( '' ).focus();
                 return  false ;
             });
         });
     </script>


用来呈现结果的div


1
2
3
4
5
6
form id= "send-message"  class = "form-inline" >
         <input id= "name"  type= "text"  value= "可以更换名字" >
         <input id= "message"  type= "text"  value= "要扯淡的内容"  />
        &nbsp; <button  class = "btn btn-success"  type= "submit" >Send</button>
     </form>
     <div id= "messages" ></div>



这里有个tornado后端的代码,实现的过程和我差不多的~我需要的朋友可以跑一下~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import  logging
import  os.path
import  uuid
import  tornado.httpserver
import  tornado.ioloop
import  tornado.options
import  tornado.web
import  tornado.websocket
def send_message(message):
     for  handler  in  ChatSocketHandler.socket_handlers:
         try :
             handler.write_message(message)
         except:
             logging.error( 'Error sending message' , exc_info=True)
class  MainHandler(tornado.web.RequestHandler):
     def  get (self):
         self.render( 'index.html' )
class  ChatSocketHandler(tornado.websocket.WebSocketHandler):
     socket_handlers =  set ()
     def open(self):
         ChatSocketHandler.socket_handlers.add(self)
         send_message( 'A new user has entered the chat room.' )
     def on_close(self):
         ChatSocketHandler.socket_handlers.remove(self)
         send_message( 'A user has left the chat room.' )
     def on_message(self, message):
         send_message(message)
def main():
     settings = {
         'template_path' : os.path.join(os.path.dirname(__file__),  'templates' ),
         'static_path' : os.path.join(os.path.dirname(__file__),  'static' )
     }
     application = tornado.web.Application([
         ( '/' , MainHandler),
         ( '/new-msg/' , ChatHandler),
         ( '/new-msg/socket' , ChatSocketHandler)
     ], **settings)
     http_server = tornado.httpserver.HTTPServer(application)
     http_server.listen( 8000 )
     tornado.ioloop.IOLoop.instance().start()
if  __name__ ==  '__main__' :
     main()



我和沈灿的对话~

104333609.jpg


沈灿和我的对话

104517224.jpg






 本文转自 rfyiamcool 51CTO博客,原文链接:http://blog.51cto.com/rfyiamcool/1269232,如需转载请自行联系原作者


相关文章
|
18天前
|
数据库 Python
Python实践:从零开始构建你的第一个Web应用
使用Python和轻量级Web框架Flask,你可以轻松创建Web应用。先确保安装了Python,然后通过`pip install Flask`安装Flask。在`app.py`中编写基本的&quot;Hello, World!&quot;应用,定义路由`@app.route(&#39;/&#39;)`并运行`python app.py`启动服务器。扩展应用,可添加新路由显示当前时间,展示Flask处理动态内容的能力。开始你的Web开发之旅吧!【6月更文挑战第13天】
42 2
|
22天前
|
Java Serverless 应用服务中间件
Serverless 应用引擎操作报错合集之部署python项目时,构建过程报错,怎么解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
14天前
|
关系型数据库 MySQL 数据库
如何使用Python的Flask框架来构建一个简单的Web应用
如何使用Python的Flask框架来构建一个简单的Web应用
27 0
|
29天前
|
存储 数据管理 测试技术
构建Python构建自动化测试框架(原理与实践)
当谈到软件质量保证时,自动化测试是一个不可或缺的步骤。Python作为一种简单易学的编程语言,具有丰富的测试框架和库,使得构建自动化测试框架变得相对简单。本文将介绍如何使用Python构建自动化测试框架,包括选择合适的测试框架、编写测试用例、执行测试和生成报告等方面。
构建Python构建自动化测试框架(原理与实践)
|
10天前
|
数据采集 机器学习/深度学习 数据可视化
利用Python和Pandas库构建高效的数据分析流程
在数据驱动的时代,数据分析已成为企业决策的关键环节。本文介绍如何利用Python编程语言及其强大的数据分析库Pandas,构建一套高效且可扩展的数据分析流程。与常规的数据分析流程不同,本文不仅涵盖数据加载、清洗、转换等基础步骤,还强调数据可视化、模型探索与评估等高级分析技巧,并通过实际案例展示如何在Python中实现这些步骤,为数据分析师提供一套完整的数据分析解决方案。
|
18天前
|
Python 存储 数据处理
【Python数据类型的奥秘】:构建程序基石,驾驭信息之海
【Python数据类型的奥秘】:构建程序基石,驾驭信息之海
|
20天前
|
消息中间件 监控 调度
构建Python中的分布式系统结合Celery与RabbitMQ
在当今的软件开发中,构建高效的分布式系统是至关重要的。Python作为一种流行的编程语言,提供了许多工具和库来帮助开发人员构建分布式系统。其中,Celery和RabbitMQ是两个强大的工具,它们结合在一起可以为你的Python应用程序提供可靠的异步任务队列和消息传递机制。
|
23小时前
|
数据采集 存储 自然语言处理
Python爬虫与数据可视化:构建完整的数据采集与分析流程
Python爬虫与数据可视化:构建完整的数据采集与分析流程
|
4天前
|
监控 网络协议 Java
使用Spring Boot和WebSocket实现实时通信
使用Spring Boot和WebSocket实现实时通信
|
1月前
|
负载均衡 安全 Java
Java一分钟之-WebSocket:实时通信协议
【6月更文挑战第1天】WebSocket是实现客户端与服务器长连接、双向通信的协议,简化实时数据传输。Java中的WebSocket实现基于JSR 356。本文涵盖WebSocket基础(持久连接、双向通信、低延迟)、工作流程、常见问题(安全、连接管理、数据编码)及Java实现示例,强调错误处理、心跳机制和资源管理的最佳实践。
63 6

相关实验场景

更多