Python: Threading does not let the rest of the program run - python

In my program, when a thread starts, only the thread runs while the rest of the program waits for it. Here is the program:
import socket
from time import sleep
import threading
import string
class IRC:
"IRC Module for python"
def __init__(self, HOST, PORT, NICK, REALNAME, IDENT):
print "New Connection"
self.s=socket.socket( )
self.s.connect((HOST, PORT))
self.s.send("USER %s %s bla :%s\r\n" % (IDENT, HOST, REALNAME))
self.s.send("NICK %s\r\n" % NICK)
self.rb="ReadBuffer"
t = threading.Thread(target=self.ping())
t.start()
print "started thread"
def read(self):
readbuffer=readbuffer+self.s.recv(1024)
temp=string.split(readbuffer, "\n")
readbuffer=temp.pop( )
return temp
def ping(self):
"Handles Pinging"
readbuffer=""
print "Started pinging"
while True:
readbuffer=readbuffer+self.s.recv(1024)
temp=string.split(self.rb, "\n")
readbuffer=temp.pop( )
for line in temp:
line=string.rstrip(line)
line=string.split(line)
if(line[0]=='PING'):
self.s.send("PONG %s\r\n" % line[1])
print("Ponged")
self.pinged=True
print "ran"
def send(self, message, channel):
self.s.send("PRIVMSG %s :%s\r\n" % (channel, message))

Since the comment already solved your problem, there's not much more to say. Here's what doc says:
class threading.Thread(group=None, target=None, name=None, args=(),
kwargs={}, *, daemon=None)
This constructor should always be called
with keyword arguments. Arguments are:
group should be None; reserved for future extension when a ThreadGroup
class is implemented.
target is the callable object to be invoked by the run() method.
Defaults to None, meaning nothing is called.
So you should set target to a callable, which is the self.ping method, rather then call it.

Related

Python 3.6 Object/Class Threading

I'm looking to create a "self contained threaded class" using Python 3.
At a high level, want I would liked to do is to spawn up 50 asynchronous device objects from my "main" class and then just use their methods as needed. This is not difficult when just dealing with objects in synchronous situation but gets cloudy quite quickly as we move to asynchronous processing. The primary idea to keep the threading self contained in the device class so my base (main.py) code stays streamlined/clean and without any of the thread management.
I don't plan on any resource sharing in this case so I think I'm clear of any thread lock issues.
Here is some sample code that I hope someone can provide some hints or samples into making it a self threaded class (meaning I don't want to manage threads at the main.py level):
Sample main.py
from deviceworker import Device
availableworkers = {'USA':'services.groupkt.com', 'IND':'services.groupkt.com'}
Activeworkers = []
for name, ip in availableworkers.items():
Activeworkers.append(Device(name, ip))
for worker in Activeworkers:
worker.checkcountry() # asynchronous call - (we don't want to wait for a response)
# The idea is to keep this code as clean as possible.
Sample Object: deviceworker.py
import urllib.request
import urllib.parse
import json
class Device:
def __init__(self, name, endpoint, preamble = 'state', port = 80 ):
self.name = name
self.connected =False
self.connection = HTTPConnection(endpoint, preamble, port)
self.getStatus()
def getStatus(self, check_for = None):
self.urlresponse = json.loads(self.connection.GET('get/USA/all')) #Use USA just to verify connection
if check_for:
pass
self.connected = True
def checkcountry(self):
print(self.connection.GET('get/%s/all' % self.name))
class HTTPConnection:
def __init__(self, endpoint, preamble = None, port = 80):
if preamble: # specificing a version after the port and before method
self.url = 'http://%s:%s/%s/' % (endpoint, port, preamble)
else:
self.url = 'http://%s:%s/' % (endpoint, port)
print('_init_ url=%s' % self.url)
def GET(self, operation):
#try:
#print('%s%s' % (self.url, operation))
with urllib.request.urlopen('%s%s' % (self.url, operation)) as f:
return f.read().decode('utf-8')
#except Exception as e:
#raise Exception("GET Request Failed")
I've stripped most of the exception handling for simplicity. The sample above should work.
--- UPDATE ---
So I think I've sort of figured it out. Still not getting the parrellism I would expect from the documentation.
import threading
import urllib.request
import urllib.parse
import json
import time
class Device(threading.Thread):
def __init__(self, name, endpoint, preamble = 'state', port = 80 ):
threading.Thread.__init__(self)
self.name = name
self.connected = False
self.connection = HTTPConnection(endpoint, preamble, port)
print('%s: __init__' % self.name)
def run(self):
self.getStatus()
print('%s: hit run()' % self.name)
def getStatus(self):
self.urlresponse = json.loads(self.connection.GET('get/USA/all')) #Use USA just to verify connection
self.connected = True
def checkcountry(self):
if (self.name == 'USA'): self.waittime = 10
else: self.waittime = 0
print('%s: Getting Codes - wait time: %s' % (self.name, self.waittime))
start_time=time.time()
time.sleep(self.waittime)
result =self.connection.GET('get/%s/all' % self.name)
elapsed_time=time.time() - start_time
print('%s: Got Codes - second: %s' % (self.name, elapsed_time))
class HTTPConnection:
def __init__(self, endpoint, preamble = None, port = 80):
if preamble: # specificing a version after the port and before method
self.url = 'http://%s:%s/%s/' % (endpoint, port, preamble)
else:
self.url = 'http://%s:%s/' % (endpoint, port)
def GET(self, operation):
with urllib.request.urlopen('%s%s' % (self.url, operation)) as f:
return f.read().decode('utf-8')
DeviceList = {'USA':'services.groupkt.com', 'IND':'services.groupkt.com'}
ActiveDevices = []
DeviceList = {'USA':'services.groupkt.com', 'IND':'services.groupkt.com'}
ActiveDevices = []
for name, ip in DeviceList.items():
print('main: creating object for: %s' % name)
newDevice = Device(name, ip)
ActiveDevices.append(newDevice)
newDevice.start()
for device in ActiveDevices:
print('main: calling checkcountry() for: %s' % device.name)
device.checkcountry()
Here are the results:
main: creating object for: USA
USA: __init__
main: creating object for: IND
IND: __init__
main: calling checkcountry() for: USA
USA: Getting Codes - wait time: 10
USA: Got Codes - second: 10.167016744613647
main: calling checkcountry() for: IND
IND: Getting Codes - wait time: 0
IND: Got Codes - second: 0.11001110076904297
I by adding in the delay to the USA search I would have expected the IND to finish first but it appears that it serialized.
I'm running this on:
Python 3.6.0 (v3.6.0:41df79263a11, Dec 23 2016, 07:18:10) [MSC v.1900 32 bit (Intel)] on win32
Here is a custom thread sample with locking worked great for me, better than using the event.
Try it in Colab.
import threading,time
i=0
luk=threading.Lock()
global i
global y
global t_num
class special_thread(threading.Thread):
"""This function starts a Thread class"""
def __init__(self, execute,threadID , name, daemon,args=(), repetitive=False,kwargs=None, interval_sec=60 ):
threading.Thread.__init__(self)
self.daemon = daemon
self.stopped = threading.Event()
self.interval_sec = interval_sec
self.execute = execute
self.name = name
if kwargs is None:
kwargs = {}
self.args = args
self.kwargs=kwargs
self.repetitive=repetitive
self.threadID = threadID
print(args)
def stop(self):
self.stopped.set()
self.join()
def run(self):
if self.repetitive:
while not self.stopped.wait(self.interval_sec):
self.execute(*self.args,**self.kwargs)
else:
self.execute(*self.args,**self.kwargs)
def center(t_num):
y=0
luk.acquire()
caller = inspect.getouterframes(inspect.currentframe())[1][3]
print(' {} is aquiring by {} '.format( caller, str(time.ctime())))
y+=t_num
print( "Inside %s()" % caller)
print('thread number is ',t_num,y)
time.sleep(2*t_num)
luk.release()
print(' {} is releasing by {} '.format( caller, str(time.ctime())))
def target_uno():
t_num=1
center(t_num)
def target_dos():
t_num=2
center(t_num)
target_uno=special_thread(execute=target_uno, args=(),repetitive=True, interval_sec=1,threadID=10004,
name='target_uno',
daemon=False )
target_dos=special_thread(execute=target_dos, args=(),repetitive=True, interval_sec=1,threadID=10004,
name='target_dos',
daemon=False )
if __name__ == "__main__":
target_uno.start()
target_dos.start()
time.sleep(20)
target_uno.stop()
target_dos.stop()

Twisted spawnProcess, send output of one process to input of another

I am trying to use twisted spawnProcess to replicate the behavior of something like this:
cat <input.txt | wc -w
This is just an example of two commands, in reality I have my own processes (say python or bash scripts or external programs) where each process reads from stdin and writes to stdout. Just like the above example, I want to pipe stdout from one process to stdin of another, and I want to do this using spawnProcess. I used some hints here:
Twisted pipe two processes with spawnProcess
but I can't get it to work. It just hangs when reading from stdin on the second spawnProcess protocol. My code is below.What am I doing wrong? How exactly can I achieve this objective? Is it better to call the second spawnProcess from within the first?
#!/usr/bin/env python
from twisted.internet import protocol
from twisted.internet import reactor
import re
import os
import sys
class CatPP(protocol.ProcessProtocol):
def __init__(self,input_data):
self.input_data=input_data
self.data = ""
def connectionMade(self):
print "connectionMade in CatPP! Now writing to stdin of cat"
print " writing this data: %s" % self.input_data
self.transport.write(self.input_data+'\n')
print " closing stdin"
self.transport.closeStdin() # tell them we're done
print " stdin closed"
def outReceived(self, data):
print "outReceived from cat! with %d bytes!" % len(data)
self.data = self.data + data
print " received this: %s" % self.data
def errReceived(self, data):
print "errReceived from cat! with %d bytes!" % len(data)
def inConnectionLost(self):
print "inConnectionLost for cat! stdin is closed! (we probably did it)"
def outConnectionLost(self):
print "outConnectionLost for cat! The child closed their stdout!"
# now is the time to examine what they wrote
print "I saw cat write this:", self.data
def errConnectionLost(self):
print "errConnectionLost for cat! The child closed their stderr."
def processExited(self, reason):
print "processExited for cat, status %d" % (reason.value.exitCode,)
def processEnded(self, reason):
print "processEnded for cat, status %d" % (reason.value.exitCode,)
class WcPP(protocol.ProcessProtocol):
def __init__(self):
self.data = ""
def connectionMade(self):
print "connectionMade! Now reading from pipe to get stdin for wp"
print " reading from stdin"
txt = sys.stdin.read()
print " Read this from stdin: %s" % (txt,)
self.transport.write(txt)
self.transport.closeStdin() # tell them we're done
def outReceived(self, data):
print "outReceived from cat! with %d bytes!" % len(data)
self.data = self.data + data
def errReceived(self, data):
print "errReceived from cat! with %d bytes!" % len(data)
def inConnectionLost(self):
print "inConnectionLost for cat! stdin is closed! (we probably did it)"
def outConnectionLost(self):
print "outConnectionLost for cat! The child closed their stdout!"
# now is the time to examine what they wrote
print "Final output:", self.data
#(dummy, lines, words, chars, file) = re.split(r'\s+', self.data)
#print "I saw %s lines" % lines
def errConnectionLost(self):
print "errConnectionLost for cat! The child closed their stderr."
def processExited(self, reason):
print "processExited for cat, status %d" % (reason.value.exitCode,)
def processEnded(self, reason):
print "processEnded for cat, status %d" % (reason.value.exitCode,)
reactor.stop()
readPipe, writePipe = os.pipe()
handle=open('junkin.txt','r')
cat_txt=handle.read()
handle.close()
pp1 = CatPP(cat_txt)
pp2 = WcPP()
reactor.spawnProcess(pp1, "cat", ["cat"], {}, childFDs={1: writePipe})
reactor.spawnProcess(pp2, "wc", ["wc", "-w"], {},childFDs={0: readPipe})
reactor.run()
try:
os.close(readPipe)
except:
print "Exception closing readPipe"
try:
os.close(writePipe)
except:
print "Exception closing writePipe"
Here is a working example.
In the case of piping through cat | wc, spawnProcess duplicates the pipes so you need to close them.
from twisted.internet import protocol
from twisted.internet import reactor
import os
class Writer(protocol.ProcessProtocol):
def __init__(self, data):
self.data = data
def connectionMade(self):
print "Writer -- connection made"
self.transport.writeToChild(0, self.data)
self.transport.closeChildFD(0)
def childDataReceived(self, fd, data):
pass
def processEnded(self, status):
pass
class Reader(protocol.ProcessProtocol):
def __init__(self):
pass
def connectionMade(self):
print "Reader -- connection made"
pass
def childDataReceived(self, fd, data):
print "Reader -- childDataReceived"
self.received = data
def processEnded(self, status):
print "process ended, got:", self.received
class WriteRead(protocol.ProcessProtocol):
def __init__(self, data):
self.data = data
def connectionMade(self):
self.transport.writeToChild(0, self.data)
self.transport.closeChildFD(0)
def childDataReceived(self, fd, data):
self.received = data
print "got data:", data
def processEnded(self, status):
print "process ended - now what?"
def test1(data):
# just call wc
p2 = reactor.spawnProcess(WriteRead(data), "wc", ["wc"], env=None, childFDs={0: "w", 1: "r"})
reactor.run()
def test2(data):
rfd, wfd = os.pipe()
p1 = reactor.spawnProcess(Writer(data), "cat", ["cat"], env=None, childFDs={0:"w", 1: wfd })
p2 = reactor.spawnProcess(Reader(), "wc", ["wc", "-w"], env=None, childFDs={0: rfd, 1: "r"})
os.close(rfd)
os.close(wfd)
reactor.run()
test2("this is a test")
Ok I figured out how to do it but without using the pipes approach from Twisted pipe two processes with spawnProcess, which I never got to work. Instead I used a class ChainableProcessProtocol that takes another ChainableProcessProtocol as an argument.This way you can chain these together, with the output of a prior protocol writing to the stdin of the next protocol. This chaining stops when the next_protocol is None. The final output is the data from the final protocol. Here is my example:
#!/usr/bin/env python
from twisted.internet import protocol
from twisted.internet import reactor, defer
import re
import os
import sys
import json
def shutdown(x):
print "Shutdown called"
reactor.stop()
class ChainableProcessProtocol(protocol.ProcessProtocol):
def __init__(self,cmd,cmdargs,input_data,next_protocol):
self.cmd=cmd
self.cmdargs=cmdargs
self.input_data=input_data
self.next_protocol=next_protocol
self.data = ""
def set_input_data(self,new_input_data):
self.input_data=new_input_data
def connectionMade(self):
print "connectionMade in %s! Now writing to stdin of cat" % self.cmd
print " writing this data: %s" % self.input_data
self.transport.write(self.input_data+'\n')
print " closing stdin"
self.transport.closeStdin() # tell them we're done
print " stdin closed"
def outReceived(self, data):
print "outReceived from %s! with %d bytes!" % (self.cmd,len(data))
self.data = self.data + data
print " received this: %s" % self.data
def errReceived(self, data):
print "errReceived from %s! with %d bytes!" % (self.cmd,len(data))
def inConnectionLost(self):
print "inConnectionLost for %s! stdin is closed! (we probably did it)" %(self.cmd,)
def outConnectionLost(self):
print "outConnectionLost for %s! The child closed their stdout!" %(self.cmd,)
# now is the time to examine what they wrote
print "I saw %s write this: %s" % (self.cmd,self.data)
#
# cmd is done, now write to next_protocol if set
#
if self.next_protocol:
print "Calling chained protocol"
self.next_protocol.set_input_data(self.data)
npcmd=self.next_protocol.cmd
npcmdargs=self.next_protocol.cmdargs
print "npcmd is %s" % (npcmd,)
print "npcmdargs is %s" % (json.dumps(npcmdargs),)
reactor.spawnProcess(self.next_protocol, npcmd, npcmdargs, {})
else:
print "No chained protocol"
def errConnectionLost(self):
print "errConnectionLost for %s! The child closed their stderr." % (self.cmd,)
def processExited(self, reason):
print "processExited for %s, status %d" % (self.cmd,reason.value.exitCode,)
def processEnded(self, reason):
print "processEnded for %s, status %d" % (self.cmd,reason.value.exitCode,)
handle=open('junkin.txt','r')
in_txt=handle.read()
handle.close()
#
# Create the last protocol first because earlier protocol(s) need it
#
pp2 = ChainableProcessProtocol("wc",["wc","-w"],'',None)
#
# The first process takes an instance of the second process as an argument
#
pp1 = ChainableProcessProtocol("cat",["cat"],in_txt,pp2)
#
# before using spawnProcess, lets create a deferred to shut down the reactor in 2 seconds
# This should give us enough time. This is only so our test script does not run forever
#
d=defer.Deferred()
d.addCallback(shutdown)
reactor.callLater(2, d.callback, '')
#
# Now spawn the first process
#
reactor.spawnProcess(pp1, pp1.cmd, pp1.cmdargs, {})
reactor.run()
print "Final output is data in pp2: %s" % (pp2.data.strip(),)
print "Done!"

Interact with executables over server in Python?

I want to run an executable on a TCP server and take its input from socket connections interactively and send the output back to the client until the executable is terminated. I was trying it with piping through Popen class of subprocess but its not helping with interaction with executable ( its just take input only one time but i want the input to be taken all the time until program exits ).
Suppose I send "1" input to the server then server must send the stdout corresponding to "1" input to client and then ask for next input and do it till the executable exits in continuation .
Just provide the socket as the standard input, output, and error of the subprocess. E.g.:
import socket
import subprocess
listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
listener.bind(('0.0.0.0', 0))
listener.listen(5)
print(listener.getsockname())
try:
while True:
client, addr = listener.accept()
subprocess.Popen(['cat'], stdin=client, stdout=client, stderr=client)
client.close()
except KeyboardInterrupt:
pass
finally:
listener.close()
This probably requires a POSIX-compliant operating system.
Here is an implementation using circuits:
server.py:
#!/usr/bin/env python
from uuid import uuid4 as uuid
from subprocess import Popen, PIPE
from circuits import handler, Component, Debugger, Event
from circuits.io import File
from circuits.net.sockets import TCPServer
from circuits.net.events import close, write
class kill(Event):
"""kill Event"""
class Command(Component):
channel = "cmd"
def __init__(self, sock, command, channel=channel):
super(Command, self).__init__(channel=channel)
self._sock = sock
self._command = command
self._buffer = None
self._p = Popen(command, shell=True, stdin=PIPE, stdout=PIPE)
self._stdin = File(
self._p.stdin, channel="{0:s}.stdin".format(self.channel)
).register(self)
self._stdout = File(
self._p.stdout, channel="{0:s}.stdout".format(self.channel)
).register(self)
self.addHandler(
handler("eof", channel=self._stdout.channel)(self._on_stdout_eof)
)
self.addHandler(
handler("read", channel=self._stdout.channel)(self._on_stdout_read)
)
def write(self, data):
self.fire(write(data), self._stdin.channel)
def kill(self):
self._p.terminate()
self.unregister()
#staticmethod
def _on_stdout_eof(self):
self.fire(kill(), self.channel)
self.fire(close(self._sock), self.parent.channel)
#staticmethod
def _on_stdout_read(self, data):
self.fire(write(self._sock, data), "server")
class Server(Component):
channel = "server"
def init(self, bind, cmd):
self.cmd = cmd
self.clients = {}
TCPServer(bind).register(self)
def connect(self, sock, host, port):
command = Command(sock, self.cmd, channel=uuid()).register(self)
self.clients[sock] = command
def disconnect(self, sock):
command = self.clients[sock]
self.fire(kill(), command.channel)
del self.clients[sock]
def read(self, sock, data):
command = self.clients[sock]
self.fire(write(data), command.channel)
server = Server(("0.0.0.0", 8000), "python app.py")
Debugger().register(server)
server.run()
app.py:
#!/usr/bin/env python
from __future__ import print_function
import sys
def function1():
print("I am function 1!")
def function2():
print("I am function 2!")
def function3():
raise SystemExit(0)
MENU_OPTIONS = (
(1, "Function 1"),
(2, "Function 2"),
(3, "Function 3")
)
FUNCTIONS = {
1: function1,
2: function2,
3: function3
}
def main():
while True:
try:
print("Menu:")
for option, description in MENU_OPTIONS:
print("{0:d}) {1:s}".format(option, description))
print()
sys.stdout.flush()
choice = raw_input("> ")
try:
FUNCTIONS[int(choice)]()
except ValueError:
print("Invalid Input")
except (KeyboardInterrupt, EOFError):
raise SystemExit(0)
if __name__ == "__main__":
main()
For an example session (this example has been thoroughly tested):
Server Session: http://codepad.org/F7qZKdKa
Client Session: http://codepad.org/ss33wgAI
Have fun! :)
Note: I'm actually the developer/author of 1[circuits]. I thought this would be a nice example to write up.

How to get the status of spawn process in twisted python?

I want to trigger many long running processes continiously. And, based on the status returned of each process executed, I need to perform other tasks. In the below example, I'm able to spawn processes, but I'm not able to capture/get the details of the spawn processes execution status returned to mail loop(i.e in CmdProtocol class).
I'm new to this twisted python concepts - Can someone help me here?
import sys
from twisted.internet.protocol import ServerFactory, ProcessProtocol
from twisted.protocols.basic import LineReceiver
from twisted.internet import reactor
from twisted.internet import protocol
import os
import signal
class MyPP(protocol.ProcessProtocol):
def __init__(self):
self.parent_id = os.getpid()
def connectionMade(self):
print "connectionMade!"
print "Parent id = %s" % self.parent_id
print "Child process id = %s" % self.transport.pid
def outReceived(self, data):
print "out", data
def errReceived(self, data):
print "error", data
def inConnectionLost(self):
print "inConnectionLost! stdin is closed! (we probably did it)"
print "Parent id = %s" % self.parent_id
print "Child process id closes STDIN= %s" % self.transport.pid
def outConnectionLost(self):
print "outConnectionLost! The child closed their stdout!"
print "Parent id = %s" % self.parent_id
print "Child process id closes STDOUT = %s" % self.transport.pid
def errConnectionLost(self):
print "errConnectionLost! The child closed their stderr."
print "Parent id = %s" % self.parent_id
print "Child process id closes ERRCONN = %s" % self.transport.pid
def processExited(self, reason):
print "processExited %s, status %d" % (self.transport.pid, reason.value.exitCode,)
def processEnded(self, reason):
print "%s processEnded, status %d" % (self.transport.pid, reason.value.exitCode,)
print "quitting"
class CmdProtocol(LineReceiver):
delimiter = '\n'
def connectionMade(self):
self.client_ip = self.transport.getPeer()
print "Client connection from %s" % self.client_ip
def processcmd(self):
pp = MyPP()
cmd = ['c:\Python27\python.exe', '-u', 'print_hi.py']
print "Calling processcmd - <%s>" % cmd
reactor.spawnProcess(pp, cmd[0], cmd[1:])
def connectionLost(self, reason):
print "Lost client connection. Reason: %s" % reason
def lineReceived(self, line):
if not line: return
# Parse the command
print 'Cmd received from %s : %s' % (self.client_ip, line)
commandParts = line.split()
if len(commandParts) > 0:
command = commandParts[0].lower()
args = commandParts[1:]
try:
print "Command received : <%s>" % command
method = getattr(self, command)
except AttributeError, e:
self.sendLine('Error: no such command.')
else:
try:
res = method()
print "Returned status:%s" % res
self.sendLine('Command executed successfully.')
except Exception, e:
self.sendLine('Error: ' + str(e))
def do_kill(self, pid):
"""kill: Kill a process (PID)"""
print 'Killing pid:%s' % pid
res = os.kill(int(pid), signal.SIGTERM)
print "Kill Status %s" % res
class MyFactory(ServerFactory):
protocol = CmdProtocol
def __init__(self):
print "Factory called"
reactor.listenTCP(8000, MyFactory())
reactor.run()
This is actually a very basic Python data structures question. You just need to refer to an instance of CmdProtocol from an instance of MyPP. Since CmdProtocol is what constructs MyPP in the first place, this is easy. Just change the construction of MyPP to look like this:
def processcmd(self):
pp = MyPP(self)
and then MyPP.__init__ to look like this:
def __init__(self, cmd_protocol):
self.parent_id = os.getpid()
self.cmd_protocol = cmd_protocol
Then, in any method on MyPP, you can access the relevant CmdProtocol instance with self.cmd_protocol.

Python, Call a class function within another class

Can you anyone please help me call the broadcast function from class BroadcastServerFactory in class test, as per attached code
I have tried so many methods of call a function from another class, but no solution
import sys
from twisted.internet import reactor
from twisted.python import log
from twisted.web.server import Site
from twisted.web.static import File
from autobahn.websocket import WebSocketServerFactory, \
WebSocketServerProtocol, \
listenWS
class test():
//call broadcast function from here
class BroadcastServerProtocol(WebSocketServerProtocol):
def onOpen(self):
self.factory.register(self)
def onMessage(self, msg, binary):
if not binary:
self.factory.broadcast("'%s' from %s" % (msg, self.peerstr))
def connectionLost(self, reason):
WebSocketServerProtocol.connectionLost(self, reason)
self.factory.unregister(self)
class BroadcastServerFactory(WebSocketServerFactory):
"""
Simple broadcast server broadcasting any message it receives to all
currently connected clients.
"""
def __init__(self, url, debug = False, debugCodePaths = False):
WebSocketServerFactory.__init__(self, url, debug = debug, debugCodePaths = debugCodePaths)
self.clients = []
self.tickcount = 0
self.tick()
def tick(self):
self.tickcount += 1
self.broadcast("'tick %d' from server" % self.tickcount)
reactor.callLater(1, self.tick)
def register(self, client):
if not client in self.clients:
print "registered client " + client.peerstr
self.clients.append(client)
def unregister(self, client):
if client in self.clients:
print "unregistered client " + client.peerstr
self.clients.remove(client)
def broadcast(self, msg):
print "broadcasting message '%s' .." % msg
for c in self.clients:
c.sendMessage(msg)
print "message sent to " + c.peerstr
if __name__ == '__main__':
if len(sys.argv) > 1 and sys.argv[1] == 'debug':
log.startLogging(sys.stdout)
debug = True
else:
debug = False
ServerFactory = BroadcastServerFactory
#ServerFactory = BroadcastPreparedServerFactory
factory = ServerFactory("ws://localhost:9000",
debug = debug,
debugCodePaths = debug)
factory.protocol = BroadcastServerProtocol
factory.setProtocolOptions(allowHixie76 = True)
listenWS(factory)
webdir = File(".")
web = Site(webdir)
reactor.listenTCP(8080, web)
reactor.run()
class test():
def __init__(self, factory):
factory.broadcast("I don't know what I'm doing!")
Meanwhile, in main...
factory = ServerFactory("ws://localhost:9000",
debug = debug,
debugCodePaths = debug)
test(factory)
This will do what you want, but it seems you're missing some core concepts about classes and instances. For the test class to call anything on another class, there needs to be an instance of it first (bar the case of static methods).

Categories