0

I am trying to send the json content from a url widh sendMessage to a client with.

def broadcast(self):
  response = urllib2.urlopen('http://localhost:8001/json?as_text=1')
  data = json.load(response)

  for c in self.clients:
     c.sendMessage(data)

I get the error

File "myServer.py", line 63, in broadcast
c.sendMessage(data)
File "/Library/Python/2.7/site-packages/autobahn-0.6.3-py2.7.egg/autobahn    /websocket.py",     line 2605, in sendMessage
self.sendMessageHybi(payload, binary, payload_frag_size, sync, doNotCompress)
  File "/Library/Python/2.7/site-packages/autobahn-0.6.3-py2.7.egg/autobahn    /websocket.py", line 2671, in sendMessageHybi
    self.sendFrame(opcode = opcode, payload = payload, sync = sync, rsv = 4 if     sendCompressed else 0)
  File "/Library/Python/2.7/site-packages/autobahn-0.6.3-py2.7.egg/autobahn/websocket.py", line 2161, in sendFrame
raw = ''.join([chr(b0), chr(b1), el, mv, plm])
exceptions.TypeError: sequence item 4: expected string, dict found
Newcoma
  • 799
  • 4
  • 13
  • 31

1 Answers1

3

sendMessage accepts a byte string or a unicode string - not a dictionary. This is because WebSockets are a transport for binary data and text data. It is not a transport for structured objects.

You can send the JSON encoded form of the dictionary but you cannot send the dictionary itself:

def broadcast(self):
    response = urllib2.urlopen('http://localhost:8001/json?as_text=1')

    for c in self.clients:
        c.sendMessage(response)

Though note that you will actually want to use twisted.web.client - not the blocking urllib2:

from twisted.internet import reactor
from twisted.web.client import Agent, readBody

agent = Agent(reactor)

def broadcast(self):
    getting = agent.request(
        b"GET", b"http://localhost:8001/json?as_text=1")
    getting.addCallback(readBody)

    def got(body):
        for c in self.clients:
            c.sendMessage(body)
    getting.addCallback(got)
    return getting
Jean-Paul Calderone
  • 47,755
  • 6
  • 94
  • 122
  • 1
    Exactly. Go with Jean-Paul's suggestions .. in particular also the use of Twisted's asynchronous Web client instead of the (blocking) Python builtin stuff. – oberstet Oct 08 '13 at 16:12
  • I get the error from twisted.web.client import readBody ImportError: cannot import name readBody – Newcoma Oct 09 '13 at 07:29
  • `readBody` was introduced in Twisted 13.1.0. You may be using an older version of Twisted than that. Upgrade, if you can. Otherwise you might want to use the (not nearly as nice) `twisted.web.client.getPage` instead. – Jean-Paul Calderone Oct 09 '13 at 10:23