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


相关文章
|
19天前
|
机器学习/深度学习 搜索推荐 算法
构建推荐系统:Python 与机器学习
推荐系统是一种利用机器学习算法和用户的历史行为数据来预测用户可能感兴趣的内容的技术。在当今的数字化时代,推荐系统已经成为许多互联网应用的核心组件,如电子商务、社交媒体和在线娱乐等。在 Python 中,我们可以使用各种机器学习库和工具来构建和实现推荐系统。
|
16天前
|
数据采集 Ubuntu Linux
不同系统下安装Python 3 #0
Anaconda安装,Windows,Linux,Mac安装Python3【2月更文挑战第6天】
57 4
|
1天前
|
前端开发 关系型数据库 MySQL
基于python+mysql的宠物领养网站系统
基于python+mysql的宠物领养网站系统
14 2
|
2天前
|
开发者 Python
Python中的元编程:扩展语言的力量
【2月更文挑战第5天】本文将探讨Python中的元编程,介绍了元编程的概念和意义,并详细讨论了Python中常用的元编程技术,如装饰器、元类和动态类型。通过元编程,我们可以在不改变语言核心的情况下,扩展Python的功能和灵活性,为开发者提供更强大的工具和框架。
|
4天前
|
存储 缓存 Python
如何在Python中实现一个简单的缓存系统?
如何在Python中实现一个简单的缓存系统?
10 1
|
5天前
|
监控 安全 Java
利用Python多线程实现实时数据处理系统
利用Python多线程实现实时数据处理系统
|
5天前
|
UED 开发者 Python
使用Python构建命令行工具:argparse和click库的使用
使用Python构建命令行工具:argparse和click库的使用
|
7天前
|
机器学习/深度学习 数据处理 算法框架/工具
Python 与机器学习:构建高效数据处理流程
在当今信息爆炸的时代,大数据处理和机器学习应用的需求日益增长。本文将介绍如何利用Python语言及其丰富的库来构建高效的数据处理流程,从而为机器学习模型的训练和优化提供可靠的数据基础。
11 2
|
7天前
|
数据采集 存储 数据可视化
微博数据可视化分析:利用Python构建信息图表展示话题热度
微博数据可视化分析:利用Python构建信息图表展示话题热度
|
19天前
|
缓存 监控 关系型数据库
构建高效的数据库应用:Python 实践
在当今数据驱动的世界中,构建高效的数据库应用程序对于企业和个人来说至关重要。Python 作为一种强大的编程语言,提供了丰富的数据库工具和库,使得开发人员能够轻松地构建高效、可靠的数据库应用程序。在本文中,我们将探讨一些关键的技术和最佳实践,以帮助你构建高效的数据库应用程序。

相关产品

  • 云迁移中心