Combine Server and Client WebSocket. - Autobahn and Twisted

87 views
Skip to first unread message

Christian C.S

unread,
Feb 13, 2019, 5:52:31 AM2/13/19
to Autobahn
Hello,

i am developing a code that will do the following :
Chat UI html & JS <--> Python (Server & Client) <--> Server Chat API

could you please give me a clue on how to pass thru the message from Chat UI to Server Chat API
and vice versa.

here's the code that we try, i think it migth be wrong.

import logging
import pprint
import json
import random
from twisted.python import log
from twisted.internet import reactor, ssl
from stompest.protocol import commands, StompFrame, StompSpec
from autobahn.twisted.websocket import WebSocketClientFactory, 
WebSocketClientProtocol, 
connectWS, WebSocketServerProtocol, WebSocketServerFactory, listenWS

from basicauth import encode

RECEIVE_CHANNEL = "/user/chat.receive"
SEND_CHANNEL = "/chat/chat.send"

CHAT_API_WS_URL="wss://xxxxxxxx/xxxx/websocket"

CHAT_API_USERNAME="xxxx-test"
CHAT_API_PASSWORD="password"
encoded_str = encode(CHAT_API_USERNAME, CHAT_API_PASSWORD)
headers = {
'Authorization': encoded_str
}

### Connect Message
connect_message = {
"type" : "CONNECT",
"from" : "csantoso",
"serviceUuid": "6b6e5fda-ed70-44df-baf3-109d3892c20f",
"commandId": 1,
"customData": {
"userDefined12": "companyCode",
"userDefined13": "[em...@example.com](mailto:em...@example.com)",
"userDefined15": "ticketReference"

```
                }
            }
```
json_connect_message = json.dumps(connect_message)

class MyServerProtocol(WebSocketServerProtocol):

```
def onConnect(self, request):
    print("=========  MyServerProtocol :: onConnect =========")
    print("MyServerProtocol :: server Client connecting: {0}".format(request.peer))
    factory = WebSocketClientFactory(CHAT_API_WS_URL, headers = headers)
    factory.protocol = MyClientProtocol

    if factory.isSecure:
        print("setting up SSL")
        contextFactory = ssl.ClientContextFactory()
    else:
        contextFactory = None

    connectWS(factory, contextFactory)

    self.client = MyClientProtocol()

def onOpen(self):
    print("=========  MyServerProtocol :: onOpen =========") 
    print("server WebSocket connection open.")

    payload = self.client.onOpen

def onMessage(self, payload, isBinary):
    print("=========  MyServerProtocol :: onMessage =========")
    if isBinary:
        print("server Binary message received: {0} bytes".format(len(payload)))
    else:
        print("server Text message received: {0}".format(payload.decode('utf8')))

    # messageFrame = commands.send(SEND_CHANNEL, body=bytes(json_connect_message, "utf-8"))
    # self.client.sendMessage(bytes(messageFrame))
    # self.sendMessage(self.client.onMessage, isBinary)

def onClose(self, wasClean, code, reason):
    print("=========  MyServerProtocol :: onClose =========")
    print("server WebSocket connection closed: {0}".format(reason))
```
class MyClientProtocol(WebSocketClientProtocol):

```
def onConnect(self, response):
    print("=========  MyClientProtocol :: onConnect =========") 
    print("MyClientProtocol :: Server connected: {0}".format(response.peer))
    

def onOpen(self):
    print("=========  MyClientProtocol :: onOpen =========") 
    print("MyClientProtocol :: WebSocket connection open.")

    # Create a connect frame
    connectStompFrame = commands.connect(login=None, passcode=None, headers=None, versions=None, host=None, heartBeats=None)
    print("MyClientProtocol :: connectMsg 1:\n%s\n" % pprint.pformat(connectStompFrame))
    self.sendMessage(bytes(connectStompFrame))

    # Subscribe
    def subscribe_call():
        print("MyClientProtocol :: Subscribing...")
        v = str(random.randint(0, 1000))
        subscribeStompFrame, token = commands.subscribe(RECEIVE_CHANNEL, { "id": v})
        self.sendMessage(bytes(subscribeStompFrame))
    
    # Subscribe
    # def connect_call():
    #     print("Sending Connect message...")
    #     print("connectMsg 2:\n%s\n" % str(bytes(json_connect_message, "utf-8")))
    #     messageFrame = commands.send(SEND_CHANNEL, body=bytes(json_connect_message, "utf-8"))
    #     self.sendMessage(bytes(messageFrame))

    # def hello():
    #     self.sendMessage(u"Hello, world!".encode('utf8'))
    #     self.sendMessage(b"\x00\x01\x03\x04", isBinary=True)
    #     self.factory.reactor.callLater(4, hello)

    # start sending messages every second ..
    reactor.callLater(1, subscribe_call)
    # reactor.callLater(3, connect_call)
    # hello()

def onSend(self, json_connect_message):
    messageFrame = commands.send(SEND_CHANNEL, body=bytes(json_connect_message, "utf-8"))
    self.sendMessage(bytes(messageFrame))

def onMessage(self, payload, isBinary):
    print("=========  MyClientProtocol :: onMessage =========") 

    print("::::: payload :::: ",payload)

    if isBinary:
        print("MyClientProtocol :: Text message received : payload : ",payload)
        print("MyClientProtocol :: Binary message received: {0} bytes".format(len(payload)))
    else:
        print("MyClientProtocol :: Text message received :: start process")
        print("MyClientProtocol :: Text message received: {0}".format(payload.decode('utf8')))
        

        if payload.decode('utf-8').startswith("CONNECTED"):
            return payload
            # self.sendMessage(payload, isBinary)
            # print("MyClientProtocol :: Connected!")

        

def onClose(self, wasClean, code, reason):
    print("=========  MyClientProtocol :: onClose =========") 
    print("MyClientProtocol :: WebSocket connection closed: {0}".format(reason))
```
if **name** == '**main**':

```
import sys

from twisted.python import log
from twisted.internet import reactor

log.startLogging(sys.stdout)

serverFactory = WebSocketServerFactory(u"ws://127.0.0.1:9000")
serverFactory.protocol = MyServerProtocol

listenWS(serverFactory)

reactor.run()
```

Christian C.S

unread,
Feb 13, 2019, 8:32:10 PM2/13/19
to Autobahn
"userDefined13": "[em...@example.com](mailto:ema...@example.com)",

Zaar Hai

unread,
Feb 13, 2019, 9:11:18 PM2/13/19
to autob...@googlegroups.com
Hi Christian,

Can you elaborate what are you trying to do?
If you want a client (publisher) to send message to multiple servers (subscribes on WAMP) - then just publish a message. If your " Python (Server & Client)" needs to works a proxy/middleware to "Server Chat API", then they have to use separate topics - you receive message in Python, do whatever is required and then forward it to "Server Chat API".

"userDefined13": "[em...@example.com](mailto:em...@example.com)",

--
You received this message because you are subscribed to the Google Groups "Autobahn" group.
To unsubscribe from this group and stop receiving emails from it, send an email to autobahnws+...@googlegroups.com.
To post to this group, send email to autob...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/autobahnws/ee41aef7-6526-4c5a-bf07-5d0fa1e23457%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Zaar

Christian C.S

unread,
Feb 14, 2019, 7:34:54 AM2/14/19
to Autobahn
Hello Zaar Hai, 

sorry for being unclear but you are correct that what we are trying to do is the "Python (server & Client)" need to works as proxy/middleware to the "Server Chat API".
What do you mean separate topics?

because currently, i am pretty confuse how to create this proxy/middleware.

thanks,
Christian.

------------------------------------------------------------------------------------------------------------------------------------------
"userDefined13": "[em...@example.com](mailto:ema...@example.com)",


--
Zaar

Zaar Hai

unread,
Feb 14, 2019, 8:49:08 AM2/14/19
to autob...@googlegroups.com
Suppose you are using pub/sub for communication. You need to have two uris - uri:a and uri:b. Browser only publishes/subscribes to uri:a. Server only publishes/subscribes to uri:b. Python server works with both and forwards messages - e.g. while handling on_event() from subscription on uri:a it publishes the messages to uri:b.

Hope this helps,
Zaar

P.S. Have you had a chance to watch this presentation? https://crossbario.com/static/presentations/microservices/#/ 
May be it can help to figure out how do want to use WAMP.


"userDefined13": "[em...@example.com](mailto:em...@example.com)",


--
Zaar

For more options, visit https://groups.google.com/d/optout.


--
Zaar

Christian C.S

unread,
Feb 14, 2019, 9:55:33 AM2/14/19
to Autobahn
Thanks again Zaar...
actually that’s the idea.

would you be able to suggest?
how to make the python subs/pubs to both uri?

because currently, we initialize
websocketclientfactory
and make connectWS 2 times.
one to uri a and 2nd one to uri b.

but it seems that we can’t pass the publish to each others

thanks again for the help
Reply all
Reply to author
Forward
0 new messages