2017-05-25 9 views
0

私は現在、自分のコンピュータとローカルホストの間にウェブソケットを接続する小さなデモを作成しようとしていますws://localhost:8080/ws。私はウェブソケットが変更のために私のコンピュータ上のファイルを監視するようにします。変更がある場合は、メッセージを送信します。 Advanced Rest Clientを使用して、接続と出力を監視しています。ファイルの変更が検出されたときにメッセージを送信する方法は? Twisted and Web Sockets

このファイルの内容を常に確認するためにクラスで使用できる特定の方法はありますか?

EDIT

私は指定されたディレクトリ内のファイルのいずれかのイベントを検出watchdogを使用して観測を実施しています。しかし、私のメッセージはsendFSEventメソッドで送信されていませんし、Webソケットに接続するとクライアントが登録されていないことに気付きました。ここで

server.py

import sys 
import os 

from watchdog.observers import Observer 
from twisted.web.static import File 
from twisted.python import log 
from twisted.web.server import Site 
from twisted.internet import reactor, defer 

from autobahn.twisted.websocket import WebSocketServerFactory, \ 
    WebSocketServerProtocol, listenWS 

from MessangerEventHandler import MessangerEventHandler 


class WsProtocol(WebSocketServerProtocol): 
    def connectionMade(self): 
     print("Connection made") 
     WebSocketServerProtocol.connectionMade(self) 

    def onOpen(self): 
     WebSocketServerProtocol.onOpen(self) 
     print("WebSocket connection open") 

    def onMessage(self, payload, isBinary): 
     print("Message was: {}".format(payload)) 
     self.sendMessage("message received") 

    def sendFSEvent(self, json): 
     WebSocketProtocol.sendMessage(self, json) 
     print('Sent FS event') 

    def onClose(self, wasClean, code, reason): 
     print("Connection closed: {}".format(reason)) 
     WebSocketServerProtocol.onClose(self, wasClean, code, reason) 


class WsServerFactory(WebSocketServerFactory): 
    protocol = WsProtocol 

    def __init__(self, url='ws://localhost', port=8080): 
     addr = url + ':' + str(port) 
     print("Listening on: {}".format(addr)) 
     WebSocketServerFactory.__init__(self, addr) 
     self.clients = [] 

    def register(self, client): 
     if not client in self.clients: 
      print("Registered client: {}".format(client)) 
      self.clients.append(client) 

    def unregister(self, client): 
     if client in self.clients: 
      print("Unregistered client: {}".format(client)) 
      self.clients.remove(client) 
     self._printConnected() 

    def _printConnected(self): 
     print("Connected clients:[") 

    def notify_clients(self, message): 
     print("Broadcasting: {}".format(message)) 
     for c in self.clients: 
      c.sendFSEvent(message) 
     print("\nSent messages") 


if __name__ == '__main__': 
    if len(sys.argv) < 2: 
     print("Usage: python server_defer.py <dirs>") 
     sys.exit(1) 

    log.startLogging(sys.stdout) 

    ffactory = WsServerFactory("ws://localhost", 8080) 
    ffactory.protocol = WsProtocol 
    listenWS(ffactory) 

    observers = [] 
    for arg in sys.argv[1:]: 
     dir_path = os.path.abspath(arg) 
     if not os.path.exists(dir_path): 
      print('{} does not exist.'.format(dir_path)) 
      sys.exit(1) 
     if not os.path.isdir(dir_path): 
      print('{} is not a directory.'.format(dir_path)) 
      sys.exit(1) 

     # Check for and handle events 
     event_handler = MessangerEventHandler(ffactory, reactor, os.getcwd()) 

     observer = Observer() 
     observer.schedule(event_handler, path=dir_path, recursive=True) 
     observer.start() 

     observers.append(observer) 

    try: 
     reactor.run() 
    except KeyboardInterrupt: 
     for obs in observers: 
      obs.stop() 
     reactor.stop() 
     print("\nGoodbye") 
     sys.exit(1) 

で私のコードで任意の助けいただければ幸いです。

は、ファイルやディレクトリを監視するための本当に適してい

+0

このアプリケーションを実行するOSを教えてください。 –

+0

今はWindowsですが、Linux(Red Hat)に切り替わります。 – Brian

+0

* nixには、定期的にチェックできるファイル( 'os.path.getmtime(path)'参照)の 'mtime'属性があります。もう1つの選択肢は、ファイルのチェックサムを計算し、それが変更されたときに動作することです。 – boardrider

答えて

1

ほとんどのエンタープライズディストリビューションは、inotifyが付属して

ブライアン、ありがとうございました。基本的な考え方は、接続されているWebソケットクライアントのリストを取得することです。次に、監視しているファイルに変更が発生したときに実行されるコールバックを作成します。このコールバック内で、クライアントを反復して'file: "blah/blah.txt" has changed'のようなメッセージを送信できます。ちょっと怪しいですが、コードスニペットはあなたのために物事をクリアする必要があります。

from functools import partial 
from twisted.internet import inotify 
from twisted.python import filepath 
# the rest of your imports ... 


class SomeServerProtocol(WebSocketServerProtocol): 
    def onConnect(self, request): 
     self.factory.append(self)  # <== append this client to the list in the factory 


def notification_callback(ignored, filepath, mask, ws_clients): 
    """ 
    function that will execute when files are modified 
    """ 
    payload = "event on {0}".format(filepath) 
    for client in ws_clients: 
     client.sendMessage(
      payload.encode('utf8'), # <== don't forget to encode the str to bytes before sending! 
      isBinary = False) 

if __name__ == '__main__': 
    root = File(".") 
    factory = WebSocketServerFactory(u"ws://127.0.01:8080") 
    factory.protocol = SomeServerProtocol 
    factory.clients = []  # <== create a container for the clients that connect 

    # inotify stuff 
    notify = partial(notification_callback, ws_clients=factory.clients) # <== use functools.partial to pass extra params 
    notifier = inotify.INotify() 
    notifier.startReading() 
    notifier.watch(filepath.FilePath("/some/directory"), callbacks=[notify]) 

    # the rest of your code ... 
+0

ありがとう!私は 'INotifyError:ウォッチを追加できませんでした '/ home/bweber/pub_sub_example/test_files'''を取得しています。私のコードは 'notifier.watch(filepath.FilePath(" test_files ")、callbacks = [notify])と書かれています。なぜ私はこのエラーが表示されますか? – Brian

+0

心配しないでください。ちょうどそのフォルダが私のWindowsマシン上にあることに気がつきました。そして私はLinuxマシンに切り替えました。ああ、私... – Brian

関連する問題