Reputation: 151
I am doing Cesare Rocchi's tutorial "How To Create A Socket Based iPhone App and Server" http://www.raywenderlich.com/3932/how-to-create-a-socket-based-iphone-app-and-server#comments
Do I need to define an attribute called 'name' in the "class IphoneChat(Protocol)" or is it inherited from "twisted.internet.protocol?" If it is inherited, how do I access it correctly?
server.py:
from twisted.internet.protocol import Factory, Protocol
from twisted.internet import reactor
class IphoneChat(Protocol):
def connectionMade(self):
self.factory.clients.append(self)
print "clients are", self.factory.clients
def connectionLost(self, reason):
self.factory.clients.remove(self)
def dataReceived(self, data):
a = data.split(':')
print a
if len(a) > 1:
command = a[0]
content = a[1]
msg = ""
if command == "iam":
self.name = content
msg = self.name + "has joined"
elif command == "msg":
msg = self.name + ": " + content
print msg
for c in self.factory.clients:
c.message(msg)
def message(self, message):
self.transport.write(message + '\n')
factory = Factory()
factory.protocol = IphoneChat
factory.clients = []
reactor.listenTCP(80, factory)
print "Iphone Chat server started"
reactor.run()
Terminal output:
Iphone Chat server started
...
--- <exception caught here> ---
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/selectreactor.py", line 150, in _doReadOrWrite
why = getattr(selectable, method)()
File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/twisted/internet/tcp.py", line 199, in doRead
rval = self.protocol.dataReceived(data)
File "server.py", line 30, in dataReceived
msg = self.name + ": " + content
exceptions.AttributeError: IphoneChat instance has no attribute 'name'
Problem solving steps so far:
Upvotes: 1
Views: 4363
Reputation: 95
You may be parsing the wrong text.
The article says to type “aim:cesare” and then "msg:hi" but your program doesn't know how to handle "aim:" as a command. So when you run "msg:hi" afterwards, self.name would not have a value. It looks like it was a typo from the article's author. The following commands should work:
"aim:cesare"
=> cesare
has joined
"msg:hi"
=> cesare
: hi
Upvotes: 0
Reputation: 7822
Well the error is quite logical
if command == "iam":
self.name = content
msg = self.name + "has joined"
elif command == "msg":
msg = self.name + ": " + content
print msg
In the first if clause you assign a value to self.name which may either rely on assumption that self.name exists somewhere, or on assumption that it is new and needs to be declared, but in elif you seem to assume with certainty that self.name already exists, it turns out it doesn't so you get an error.
I guess your safest option consists of simply adding self.name at the beginning of dataReceived method:
def dataReceived(self, data):
self.name = ""
this will get rid of the error. As an alternative you could also add self.name to init method of IphoneChat.If you need self.name in other functions not only in dataReceived then adding init with self.name is the way to go, but from your code it seems you only need it in datareceived so just add it there. Adding self.name in init would look like this:
class IphoneChat(Protocol):
def __init__(self):
self.name = ""
or you can also simply do
class IphoneChat(Protocol):
name = ""
and then go on with name instead of self.name.
Upvotes: 2