如何在检测到文件更改时发送消息?扭曲和Web套接字

如何在检测到文件更改时发送消息?扭曲和Web套接字

问题描述:

我目前正在尝试创建一个小型演示,其中我的电脑和我的本地主机之间连接了一个Web套接字ws://localhost:8080/ws。我想让网络套接字监视计算机上的文件以进行更改。如果有变化,请发送消息。使用Advanced Rest Client监视连接和输出。如何在检测到文件更改时发送消息?扭曲和Web套接字

有没有一种特定的方法可以用于课堂上不断检查这个文件的内容?

编辑

我已经实现了使用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

您将在哪个操作系统上运行此应用程序? –

+0

Windows现在,但将切换到Linux(红帽)。 – Brian

+0

在* nix中,有一个文件的'mtime'属性(参见'os.path.getmtime(path)'),您可以定期检查它。另一种选择是计算文件的校验和,并在更改时采取行动。 – boardrider

大多数企业发行版都配备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