0

当任何客户端向服务器发送一些消息时,我想编辑所有客户端QTextBrowser日志。

我的预期程序是这样的:

[client]enter -> [client]chatUI.handleEnter -> (RFC)[server]exposed_send -> [server]broadcast -> (RFC)[clients]update.emit() -> [clients]listen -> 日志已更改

当我运行此代码时,其他客户端日志不会更改,只有向服务器提供输入的客户端具有更新的日志。

我如何解决这个问题以正确更新所有客户端?

聊天服务器.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()

聊天客户端.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_())

聊天界面.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