0

QTextBrowserクライアントがサーバーにメッセージを送信したときに、すべてのクライアント ログを編集したいと考えています。

私の意図した手順はこれです:

[client]enter -> [client]chatUI.handleEnter -> (RFC)[server]exposed_send -> [server]broadcast -> (RFC)[clients]update.emit() -> [clients]listen -> log changed

このコードを実行すると、他のクライアントのログは変更されず、サーバーに入力を与えるクライアントのみがログを更新します。

これを解決してすべてのクライアントを適切に更新するにはどうすればよいですか?

chat_server.py

import rpyc
import random
import string
from threading import RLock

users = dict()
callbacks = dict()
user_num = 0
lock = RLock()
buf = dict()

class chatService(rpyc.Service):

    def on_connect(self):
        global user_num
        with lock:
            user_num = user_num+1
        print ("connect user: %d" % user_num)

    def on_disconnect(self):
        global user_num
        with lock:
            user_num = user_num-1
        print ("disconnect user: %d" % user_num)

    def exposed_accept(self, idt, callback):
        with lock:
            global users
            global callbacks
            if not isinstance(idt, str) or len(idt) != 6:
                return False
            elif idt in users:
                return -1
            else:
                pw = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(32))
                users[idt] = pw
                callbacks[idt] = rpyc.async(callback)
                return pw

    def exposed_send(self, target, msg, idt, pw):
        print ('here')
        name = self.identify(idt, pw)
        if name == False:
            print ('here2')
            return False
        else:
            print ('here3')
            global callbacks
            if target == None:
                self.broadcast("[%s] %s" % (name, msg))
            elif msg.target in callbacks:
                self.send("[%s] %s" %(name, msg), target)
            else:
                return False

    def exposed_order(self, msg, idt, pw):
        pass

    def identify(self, idt, pw):
        global users
        if users[idt] == pw:
            return idt
        else:
            return False

    def broadcast(self, msg):
        with lock:
            print("bloadcast calls")
            global callbacks
            global buf
            for user, callback in callbacks.items():
                if user not in buf or buf[user] == None:
                    buf[user] = (msg,)
                else:
                    buf[user] = buf[user] + (msg,)
                callback()

    def send(self, msg, target):
        global callbacks
        global buf
        if user not in buf or buf[user] == None:
            buf[target] = (msg,)
        else:
            buf[target] = buf[target] + (msg,)

        callbacks[target]()

    def exposed_get_buf(self, user):
        global buf
        temp = buf[user]
        buf[user] = None
        return temp

if __name__ == '__main__':
    from rpyc.utils.server import ThreadedServer
    t = ThreadedServer(chatService, port = 3743)
    t.start()

chat_client.py

from chatUI import *
import rpyc
import random
import string

if __name__ == '__main__':

    service = rpyc.connect('floating.tk', 3743)
    app, chat = UIReady(service)

    while True:
        idt = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6))
        pw = service.root.accept(idt, chat.update.update.emit)
        if pw != False and pw != -1:
            break
    chat.idt = idt
    chat.pw = pw

    sys.exit(app.exec_())

chatUI.py

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

class Updater(QObject):
    update = pyqtSignal()

class Chat(QWidget):

    log = None
    enter = None

    def __init__(self, service) :
        super().__init__()
        self.service = service
        self.idt = None
        self.pw = None
        self.initUI()
        self.update = Updater()
        self.update.update.connect(self.listen)

    def initUI(self):

        logLabel = QLabel('chat log')
        enterLabel = QLabel('enter')
        self.log = QTextBrowser()
        self.enter = QLineEdit()

        self.enter.returnPressed.connect(self.handleEnter)

        layout = QGridLayout()
        layout.addWidget(logLabel, 0, 0)
        layout.addWidget(self.log, 0, 1, 5, 1)
        layout.addWidget(enterLabel, 6, 0)
        layout.addWidget(self.enter, 6, 1)

        self.setLayout(layout)

        self.setWindowTitle('chat')
        self.resize(600, 600)
        self.show()

    def handleEnter(self):
        msg = self.enter.text()
        self.enter.setText("")
        self.service.root.send(None, msg, self.idt, self.pw)
        print('get enter')

    def listen(self):
        msg = self.service.root.get_buf(self.idt)
        for m in msg:
            self.log.append(m)


def UIReady(service):
    app = QApplication(sys.argv)
    chat = Chat(service)
    return app, chat
4

0 に答える 0