I just want to send a message... browser to server - button presses/whatever. server to browser - ROS information (other than video, e.g., battery level.)
The examples clearly show how to receive and send a message. In the examples/server.py code:
# pc is an RTCPeerConnection
@pc.on("datachannel")
def on_datachannel(channel):
@channel.on("message")
def on_message(message):
if isinstance(message, str) and message.startswith("ping"):
channel.send("pong" + message[4:])
I've searched and haven't found any 'send' examples that aren't essentially responding to a received "message" (python side) or "onopen" (js). This of course gives full context and resides inside an async function (python side.)
What I'd like to do is just have a simple, global function akin to this:
var dc = None # global, set in event "datachannel"
def sendMessage(msg) # This is what I want! Both python and JS side
if (dc != None):
dc.send(msg)
async def offer(request):
global dc
...
@pc.on("datachannel")
def on_datachannel(channel):
global dc
dc = channel
# and set dc to None if connection fails or ended
This fails -
Exception in thread Thread-4:
Traceback (most recent call last):
File "/usr/lib/python3.10/threading.py", line 1016, in _bootstrap_inner
self.run()
File "/usr/lib/python3.10/threading.py", line 1378, in run
self.function(*self.args, **self.kwargs)
File "/home/pg/workspaces/isaac_ros-dev/src/pywebrtc/pywebrtc/server.py", line 112, in betterPong
sendMessage("betterPong")
File "/home/pg/workspaces/isaac_ros-dev/src/pywebrtc/pywebrtc/server.py", line 107, in sendMessage
dc.send(msg)
File "/home/pg/.local/lib/python3.10/site-packages/aiortc/rtcdatachannel.py", line 187, in send
self.transport._data_channel_send(self, data)
File "/home/pg/.local/lib/python3.10/site-packages/aiortc/rtcsctptransport.py", line 1808, in _data_channel_send
asyncio.ensure_future(self._data_channel_flush())
File "/usr/lib/python3.10/asyncio/tasks.py", line 615, in ensure_future
return _ensure_future(coro_or_future, loop=loop)
File "/usr/lib/python3.10/asyncio/tasks.py", line 634, in _ensure_future
loop = events._get_event_loop(stacklevel=4)
File "/usr/lib/python3.10/asyncio/events.py", line 656, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-4'.
/usr/lib/python3.10/threading.py:1018: RuntimeWarning: coroutine 'RTCSctpTransport._data_channel_flush' was never awaited
I'm a newb on asyncio in Python. If I put async in front of the function and await on the send, I get
server.py:112: RuntimeWarning: coroutine 'sendMessage' was never awaited
Hopefully, this is simple! :) Best!
Here's a working solution for the Python side... Diving down into asyncio and a stackoverflow answer:
Works. Is it efficient to create a new coroutine for each send? to be determined...