经过python和websocket捕获进程的输出到网页上

WebSocket是html5中实现的一种新协议,相比http优点的是它是一种双向通讯协议,不用像经过ajax长轮询请求服务器去实现相似的需求。咱们先来看下须要的基础知识:javascript

一、autobahn: autobahn是websocket的python实现。html

二、twisted: Twisted是一个python异步解决方案,基于事件驱动的网络引擎框架。html5


autobahn官方的教程很不错:http://autobahn.ws/python/websocket/programming.html#sending-messages java

twisted启动进程的例子:https://twistedmatrix.com/documents/13.0.0/core/howto/process.html node


参考国外某大神的例子:https://tomforb.es/displaying-a-processes-output-on-a-web-page-with-websockets-and-python python

# 先装包
pip install autobahn twisted

# server程序
[root@node_172_16_214_230 ~]# cat test_run.py
#!/usr/bin/env python

from autobahn.twisted.websocket import WebSocketServerFactory
from autobahn.twisted.websocket import WebSocketServerProtocol
from twisted.internet import reactor, protocol
from twisted.python import msg

COMMAND_NAME = sys.argv[1]
COMMAND_ARGS = sys.argv[1:]

class MyProcessProtocol(protocol.ProcessProtocol):

    def __init__(self, wf):
        self.ws = ws
        self.buffer = []

    def outReceived(self, data):
        self.ws.broadcast(data)
        self.buffer.append(data)
        self.buffer = self.buffer[-10:]

    def errReceived(self, data):
        print "Error: %s" % data


class MyServerProtocol(WebSocketServerProtocol):

   def onConnect(self, request):
       print("Client connecting: {0}".format(request.peer))

   def onOpen(self):
      self.factory.register(self)
      for line in self.factory.process.buffer:
          self.sendMessage(line)

   def connectionLost(self, reason):
      print("WebSocket connection lost: {0}".format(reason))
      self.factory.unregister(self)      
   

class MyWebSocketServerFactory(WebSocketServerFactory):

   def __init__(self, *args, **kwargs):
      super(MyWebSocketServerFactory, self).__init__(*args, **kwargs)
      self.clients = []
      self.process = MyProcessProtocol(self)
      reactor.spawnProcess(self.process,COMMAND_NAME, COMMAND_ARGS, {}, usePTY=True)

   def register(self, client):
      msg("Registered client %s" % client)
      if client not in self.clients:
         self.clients.append(client)

   def unregister(self, client):
      msg("Unregistered client %s" % client)
      if client in self.clients:
         self.clients.remove(client)

   def broadcast(self, message):
      for client in self.clients:
         client.sendMessage(message)


if __name__ == '__main__':
   import sys

   from twisted.python import log
   log.startLogging(sys.stdout)

   factory = MyWebSocketServerFactory("ws://0.0.0.0:9000")
   factory.protocol = MyServerProtocol

   reactor.listenTCP(9000, factory)
   reactor.run()
   
   
# 客户端就是浏览器了
[root@node_172_16_214_230 ~]# cat /var/www/html/index.html
<html>
   <head>
      <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
      <script type="text/javascript">
         window.onload = function() {
            window.webSocket = new WebSocket("ws://172.16.214.230:9000");
            window.webSocket.onmessage = function(e) {
               console.log("Got echo: " + e.data);
                $("#output").append(e.data);
            }
         }
      </script>
   </head>
   <body>
      <h1>Ping output:</h1>
      <pre id="output">

      </pre>
   </body>
</html>


# 测试
# 启动server端
[root@node_172_16_214_230 ~]# python runner.py tail -f /var/log/httpd/access_log
2016-10-24 15:24:29+0000 [-] Log opened.
2016-10-24 15:24:29+0000 [-] Running process tail with args ['tail', '-f', '/var/log/httpd/access_log']
2016-10-24 15:24:29+0000 [-] WebSocketProcessOutputterThingFactory starting on 9000
2016-10-24 15:24:29+0000 [-] Starting factory <__main__.WebSocketProcessOutputterThingFactory object at 0x2447690>

# 客户端测试
登陆
相关文章
相关标签/搜索