Skip to main content
 首页 » 编程设计

Python之Twisted 和 PyAudio + 聊天

2025年05月04日11telwanggs

我一直在玩弄 Twisted 扩展,并玩弄过聊天室之类的系统。但是我想扩展它。截至目前,它仅支持使用用户名等的多客户端聊天。但我想尝试使用 pyAudio 扩展来构建一种 VoIP 应用程序。我在客户端有一个 clientFactory 和一个简单的 echo 协议(protocol),在服务器上有一个 serverFactory 和协议(protocol)。但我不完全确定如何以此为基础。执行此类操作的最佳方法是什么?

代码在您需要时提供帮助 客户端.py:

import wx 
from twisted.internet import wxreactor 
wxreactor.install() 
 
# import twisted reactor 
import sys 
from twisted.internet import reactor, protocol, task 
from twisted.protocols import basic 
 
 
class ChatFrame(wx.Frame): 
 
    def __init__(self): 
        wx.Frame.__init__(self, parent=None, title="WhiteNOISE") 
        self.protocol = None  # twisted Protocol 
 
        sizer = wx.BoxSizer(wx.VERTICAL) 
        self.text = wx.TextCtrl(self, style=wx.TE_MULTILINE | wx.TE_READONLY) 
        self.ctrl = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER, size=(300, 25)) 
 
        sizer.Add(self.text, 5, wx.EXPAND) 
        sizer.Add(self.ctrl, 0, wx.EXPAND) 
        self.SetSizer(sizer) 
        self.ctrl.Bind(wx.EVT_TEXT_ENTER, self.send) 
 
 
    def send(self, evt): 
        self.protocol.sendLine(str(self.ctrl.GetValue())) 
        self.ctrl.SetValue("") 
 
 
class DataForwardingProtocol(basic.LineReceiver): 
    def __init__(self): 
        self.output = None 
 
    def dataReceived(self, data): 
        gui = self.factory.gui 
 
        gui.protocol = self 
        if gui: 
            val = gui.text.GetValue() 
            gui.text.SetValue(val + data) 
            gui.text.SetInsertionPointEnd() 
 
    def connectionMade(self): 
        self.output = self.factory.gui.text  # redirect Twisted's output 
 
 
class ChatFactory(protocol.ClientFactory): 
    def __init__(self, gui): 
        self.gui = gui 
        self.protocol = DataForwardingProtocol 
 
    def clientConnectionLost(self, transport, reason): 
        reactor.stop() 
 
    def clientConnectionFailed(self, transport, reason): 
        reactor.stop() 
 
 
if __name__ == '__main__': 
    app = wx.App(False) 
    frame = ChatFrame() 
    frame.Show() 
    reactor.registerWxApp(app) 
    reactor.connectTCP("192.168.1.115", 5001, ChatFactory(frame)) 
    reactor.run() 

服务器.py:

from twisted.internet import reactor, protocol 
from twisted.protocols import basic 
import time 
 
def t(): 
    return "["+ time.strftime("%H:%M:%S") +"] " 
 
class EchoProtocol(basic.LineReceiver): 
    name = "Unnamed" 
 
    def connectionMade(self): 
    #on client connection made 
    self.sendLine("WhiteNOISE") 
        self.sendLine("Enter A Username Below...") 
        self.sendLine("") 
        self.count = 0 
        self.factory.clients.append(self) 
        print t() + "+ Connection from: "+ self.transport.getPeer().host 
 
    def connectionLost(self, reason): 
    #on client connection lost 
        self.sendMsg("- %s left." % self.name) 
        print t() + "- Connection lost: "+ self.name 
        self.factory.clients.remove(self) 
 
    def lineReceived(self, line): 
    #actions to do on message recive 
        if line == '/quit': 
    #close client connection 
            self.sendLine("Goodbye.") 
            self.transport.loseConnection() 
            return 
        elif line == "/userlist": 
    #send user list to single client, the one who requested it 
            self.chatters() 
            return 
    elif line.startswith("/me"): 
    #send an action formatted message 
        self.sendLine("**" + self.name + ": " + line.replace("/me","")) 
        return 
    elif line == "/?": 
        self.sendLine("Commands: /? /me /userlist /quit") 
        return 
        if not self.count: 
            self.username(line) 
        else: 
            self.sendMsg(self.name +": " + line) 
 
    def username(self, line): 
    #check if username already in use 
        for x in self.factory.clients: 
            if x.name == line: 
                self.sendLine("This username is taken; please choose another") 
                return 
 
        self.name = line 
        self.chatters() 
        self.sendLine("You have been connected!") 
        self.sendLine("") 
        self.count += 1 
        self.sendMsg("+ %s joined." % self.name) 
        print '%s~ %s connected as: %s' % (t(), self.transport.getPeer().host, self.name) 
 
    def chatters(self): 
        x = len(self.factory.clients) - 1 
        s = 'is' if x == 1 else 'are' 
        p = 'person' if x == 1 else 'people' 
        self.sendLine("There %s %i other %s connected:" % (s, x, p) ) 
 
        for client in self.factory.clients: 
            if client is not self: 
                self.sendLine(client.name) 
        self.sendLine("") 
 
    def sendMsg(self, message): 
    #send message to all clients 
        for client in self.factory.clients: 
            client.sendLine(t() + message) 
 
 
class EchoServerFactory(protocol.ServerFactory): 
    protocol  = EchoProtocol 
    clients = [] 
 
if __name__ == "__main__": 
    reactor.listenTCP(5001, EchoServerFactory()) 
    reactor.run() 

请您参考如下方法:

看看Divmod Sine , SIP 应用服务器。基本思想是您的应用程序中需要一个额外的网络服务器来支持应用程序的 VoIP 部分。