设为首页 收藏本站
查看: 2496|回复: 0

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

[复制链接]

尚未签到

发表于 2018-8-1 11:34:39 | 显示全部楼层 |阅读模式
  先放一个小demo~
  用html5的websocket实现的聊天平台。后端用的是python bottle框架。
  后期要改成监控,可能要联合saltstack做实时的监控。
  像上篇博客说的那样,实时监控就那点东西,就是接收数据、显示数据 。
  像下面这样:
  原文地址:http://rfyiamcool.blog.51cto.com/1030776/1269232
DSC0000.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请求及销毁请求,减少网络带宽资源的占用,同时也节省服务器资源;
建立连接的握手  
当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,表示协议错误),以关闭连接。
DSC0001.jpg

  ws的连接状态:
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来搞搞
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的方式。
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 u 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
<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
form>  <input type="text" value="可以更换名字">
  <input type="text" value="要扯淡的内容" />
  &nbsp; <button type="submit">Send</button>
  </form>
  <div></div>
  这里有个tornado后端的代码,实现的过程和我差不多的~我需要的朋友可以跑一下~
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()
  我和沈灿的对话~
DSC0002.jpg

  沈灿和我的对话
DSC0003.jpg

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-544708-1-1.html 上篇帖子: 用Saltstack的modules和grains实现实时监控平台 下篇帖子: 关于Saltstack halite 配置管理及二次开发ui [原salt-ui]
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表