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


相关文章
|
16天前
|
存储 人工智能 搜索推荐
【python】python用户管理系统[简易版](源码+报告)【独一无二】
【python】python用户管理系统[简易版](源码+报告)【独一无二】
|
22天前
|
Python
Python实现简易天气查询系统
Python实现简易天气查询系统
26 4
|
3天前
|
数据采集 NoSQL 搜索推荐
五一假期畅游指南:Python技术构建的热门景点分析系统解读
五一假期畅游指南:Python技术构建的热门景点分析系统解读
|
4天前
|
数据库 开发者 Python
Python中使用Flask构建简单Web应用的例子
【4月更文挑战第15天】Flask是一个轻量级的Python Web框架,它允许开发者快速搭建Web应用,同时保持代码的简洁和清晰。下面,我们将通过一个简单的例子来展示如何在Python中使用Flask创建一个基本的Web应用。
|
8天前
|
JavaScript 搜索推荐 前端开发
音乐发现平台:借助Python和Vue构建个性化音乐推荐系统
【4月更文挑战第11天】本文介绍了如何使用Python和Vue.js构建个性化音乐推荐系统。首先确保安装Python、Node.js、数据库系统和Git。后端可选择Flask或Django搭建RESTful API,处理歌曲数据。前端利用Vue.js创建用户界面,结合Vue CLI、Vuex和Vue Router实现功能丰富的SPA。通过Vuex管理状态,Axios与后端通信。这种前后端分离的架构利于协作和系统扩展,助力打造定制化音乐体验。
|
8天前
|
机器学习/深度学习 人工智能 算法
|
11天前
|
人工智能 机器人 测试技术
【Python】Python仓储管理系统(源码)【独一无二】
【Python】Python仓储管理系统(源码)【独一无二】
|
16天前
|
人工智能 机器人 测试技术
【Python】Python房屋销售系统(源码)【独一无二】(课程设计)
【Python】Python房屋销售系统(源码)【独一无二】(课程设计)
|
19天前
|
机器学习/深度学习 数据采集 算法
基于Apriori关联规则的电影推荐系统(附python代码)
这是一个基于Apriori算法的电影推荐系统概览。系统通过挖掘用户评分数据来发现关联规则,例如用户观看某部电影后可能感兴趣的其他电影。算法核心是逐层生成频繁项集并设定最小支持度阈值,之后计算规则的置信度。案例中展示了数据预处理、频繁项集生成以及规则提取的过程,具体包括用户评分电影的统计分析,如1-5部电影的评分组合。最后,通过Python代码展示了Apriori算法的实现,生成推荐规则,并给出了一个简单的推荐示例。整个过程旨在提高推荐的精准度,基于用户已评分的电影推测他们可能尚未评分但可能喜欢的电影。
基于Apriori关联规则的电影推荐系统(附python代码)
|
22天前
|
Python
Python实现简易文件管理系统
Python实现简易文件管理系统
27 5