通过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,如需转载请自行联系原作者


相关文章
|
3天前
|
JSON API 数据库
使用Python和Flask构建简单的RESTful API
使用Python和Flask构建简单的RESTful API
13 6
|
3天前
|
Python
使用Python和Flask构建简单的Web应用
使用Python和Flask构建简单的Web应用
15 6
|
2天前
|
数据可视化 数据处理 开发者
构建高效的数据流图:Python与PyGraphviz的实践
【9月更文挑战第13天】在本文中,我们将探索如何利用Python和PyGraphviz库来创建和操作数据流图。我们将通过一个具体示例,展示如何从零开始构建一张数据流图,并讨论如何优化图表以提高可读性。文章旨在为初学者提供一个清晰的入门指南,同时为有经验的开发者提供一些高级技巧。
|
5天前
|
消息中间件 Kafka 数据安全/隐私保护
Python IPC实战指南:构建高效稳定的进程间通信桥梁
【9月更文挑战第11天】在软件开发中,随着应用复杂度的提升,进程间通信(IPC)成为构建高效系统的关键。本文通过一个分布式日志处理系统的案例,介绍如何使用Python和套接字实现可靠的IPC。案例涉及定义通信协议、实现日志发送与接收,并提供示例代码。通过本教程,你将学会构建高效的IPC桥梁,并了解如何根据需求选择合适的IPC机制,确保系统的稳定性和安全性。
19 5
|
7天前
|
JSON 安全 数据安全/隐私保护
实战指南:Python中OAuth与JWT的完美结合,构建安全认证防线
【9月更文挑战第9天】当今互联网应用的安全性至关重要,尤其在处理用户数据和个人隐私时。OAuth 和 JWT 是两种广泛使用的认证机制,各具优势。本文探讨如何在 Python 中结合 OAuth 和 JSON Web Tokens (JWT) 构建安全可靠的认证系统。OAuth 允许第三方应用获取有限访问权限而不暴露用户密码;JWT 则是一种轻量级数据交换格式,用于安全传输信息。结合使用这两种技术,可以在确保安全性的同时简化认证流程。
10 4
|
5天前
|
存储 安全 数据库
双重防护,无懈可击!Python AES+RSA加密方案,构建最强数据安全堡垒
【9月更文挑战第11天】在数字时代,数据安全至关重要。AES与RSA加密技术相结合,构成了一道坚固防线。AES以其高效性保障数据加密,而RSA则确保密钥安全传输,二者相辅相成,提供双重保护。本文通过Python代码示例展示了这一加密方案的魅力,强调了其在实际应用中的重要性和安全性。使用HTTPS等安全协议传输加密密钥和密文,确保数据在数字世界中自由流通而无忧。
12 1
|
6天前
|
数据采集 JavaScript 前端开发
构建你的首个Python网络爬虫
【9月更文挑战第8天】本文将引导你从零开始,一步步构建属于自己的Python网络爬虫。我们将通过实际的代码示例和详细的步骤解释,让你理解网络爬虫的工作原理,并学会如何使用Python编写简单的网络爬虫。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开网络数据获取的新世界。
|
11天前
|
算法 程序员 Linux
Python编程入门:构建你的第一个程序
【9月更文挑战第4天】编程是现代技术发展的基石,而Python作为一门简洁、易学且功能强大的编程语言,已成为众多初学者的首选。本文将引导你通过一个简单的Python程序,探索编程世界的奥秘,并了解如何利用Python实现基本的算法逻辑。无论你是完全的新手还是希望巩固基础的开发者,这篇文章都将为你提供一个清晰的学习路径。从安装Python环境开始,到编写第一个程序,我们将一步步揭开编程的神秘面纱。
|
15天前
|
数据采集 JavaScript 前端开发
构建简易Python爬虫:抓取网页数据入门指南
【8月更文挑战第31天】在数字信息的时代,数据抓取成为获取网络资源的重要手段。本文将引导你通过Python编写一个简单的网页爬虫,从零基础到实现数据抓取的全过程。我们将一起探索如何利用Python的requests库进行网络请求,使用BeautifulSoup库解析HTML文档,并最终提取出有价值的数据。无论你是编程新手还是有一定基础的开发者,这篇文章都将为你打开数据抓取的大门。
|
15天前
|
Java 缓存 数据库连接
揭秘!Struts 2性能翻倍的秘诀:不可思议的优化技巧大公开
【8月更文挑战第31天】《Struts 2性能优化技巧》介绍了提升Struts 2 Web应用响应速度的关键策略,包括减少配置开销、优化Action处理、合理使用拦截器、精简标签库使用、改进数据访问方式、利用缓存机制以及浏览器与网络层面的优化。通过实施这些技巧,如懒加载配置、异步请求处理、高效数据库连接管理和启用GZIP压缩等,可显著提高应用性能,为用户提供更快的体验。性能优化需根据实际场景持续调整。
40 0