經過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>

# 客戶端測試
登陸
相關文章
相關標籤/搜索