Python - Twisted和PyAudio + Chat

时间:2012-10-17 01:16:23

标签: python twisted voip pyaudio

我一直在玩Twisted扩展程序并且在聊天室系统中愚弄了。但是我想扩展它。截至目前,它仅支持具有用户名等的多客户端聊天。但我想尝试使用pyAudio扩展来构建一种VoIP应用程序。我在客户端有一个clientFactory和一个简单的echo协议,在服务器上有一个serverFactory和protocol。但我不完全确定如何建立这个。做这样的事情最好的方法是什么?

代码可在您需要时提供帮助 client.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()

server.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()

1 个答案:

答案 0 :(得分:0)

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