0

I stablish the coroutine WebSocket link, but only can send a message inside this coroutine, my question is how to send a message outside this coroutine with current client


#!/usr/bin/env python3
import  os,asyncio , threading,dotenv, aiohttp ,time,serial_asyncio,aiofiles

from aiohttp         import web, MultipartWriter

from aiohttp.web     import middleware

temple="""
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">  
    var _Connection;
    var link="ws://"+location.host+"/ws"; 
    window.onload = function ()  {setTimeout( ini_ws , 400);}

    function ini_ws()
    {
    _Connection = new WebSocket( link); 
    _Connection.onerror = function (error){document.getElementById('_link').value="Link Broken";  document.getElementById('_link').style.backgroundColor ="#FFA500"; }
    _Connection.close = function (error)  {document.getElementById('_link').value="Disconnected"; document.getElementById('_link').style.backgroundColor ="#FFE4E1";} //gray
    _Connection.onopen = function (evt)   {document.getElementById('_link').value="Connected";    document.getElementById('_link').style.backgroundColor ="#7FFF00";_Connection.send('Hello web server on Firefly' ); }
    _Connection.onmessage = function(INCOME){document.getElementById('recieve_dats').value+=INCOME.data+'\n'; }  

    setInterval(check_WS, 500); 
    }
    function check_WS(){
          if(  _Connection.readyState == 3 ) {document.getElementById('_link').style.backgroundColor ="#FFA500"; ini_ws();}
    else  if(  _Connection.readyState == 0 ) {document.getElementById('_link').style.backgroundColor ="#DC143C";  } 
    else  if(  _Connection.readyState == 2 ) {document.getElementById('_link').style.backgroundColor ="#FF0000";  }
      }
    function clear_console() {document.getElementById("recieve_dats").value=""}
    function send_command(){
        var v=document.getElementById("send_command_value").value;
        if(v) _Connection.send(v )
        document.getElementById("send_command_value").value="";
    }   
</script>
</head>
<body>
    <h2>websocket link</h2>
    <input  type="button" id="_link" onclick="ini_ws();return false;"  name=""   value="Disconnected" >
    <h2>incoming data</h2>
    <div>
        <textarea  id="recieve_dats"   > </textarea>
        <p>Console in       <button onclick="clear_console();return false;" >Clear Console</button> </p>        
    </div>
    <h2>send data to server</h2>
    <div >
        <p>Console out  <button onclick="send_command();return false;"  >Send Command</button> </p>
        <input id="send_command_value"  type="text" >            
    </div>
</body>
</html>
"""

INDEX_File=os.path.join(os.path.dirname(__file__), 'ws.html'); 
GlobalWS=GlobalRequest=None

async def websocket_handler(request):    

    print("websocket_handler");
    ws =web.WebSocketResponse()
    await ws.prepare(request)
    #request.app["websockets"].add(ws)
    GlobalWS=ws
    GlobalRequest=request
    async for msg in ws:
        if msg.type == aiohttp.WSMsgType.TEXT:
            Income=msg.data;
            print(Income) 
            await ws.send_str("got your message website")
    #request.app["GlobalWS"]=None;#.remove(ws) 
    #request.app['websockets'].remove(ws)
    return ws

async def websockets_clear(app):
    print("websockets_clear");
    for ws in app['websockets']:
        await ws.close()
    app['websockets'].clear()


async def handle_index_page(request):
    async with aiofiles.open(INDEX_File, mode='r') as index_file:
        index_contents = await index_file.read()
    return web.Response(text=index_contents, content_type='text/html')#return web.Response(text=temple, content_type='text/html')


async def send_ws(s):
    ws = web.WebSocketResponse()    
    await ws.prepare(GlobalRequest)
    await ws.send_str(s)

async def serialRead(f):
    print("send serialRead")
    while True:
        print("sending......")
        await send_ws("helo web site ")
        await asyncio.sleep(1/f); 



async def setup_server(loop, address, port):
    app = web.Application(loop=loop)
    app.router.add_route('GET', "/", handle_index_page)
    app.router.add_route('GET', '/ws', websocket_handler)
    app["GlobalWS"] = set()
    app.on_shutdown.append(websockets_clear)
    app["threads"] = threading.Event()
    print("setup_server done");
    return await loop.create_server(app.make_handler(), address, port)

def server_begin():
    ip='0.0.0.0';port=8080
    loop = asyncio.get_event_loop()
    asyncio.run_coroutine_threadsafe(serialRead(1) , loop)
    asyncio.run_coroutine_threadsafe(setup_server(loop, ip,port ), loop)
    #coro = serial_asyncio.create_serial_connection(loop, Output, '/dev/ttyUSB0', baudrate=115200)
    print("Server ready!",ip,port)
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        print("Shutting Down!")
        loop.close()

if __name__ == '__main__':
    server_begin()

this code stop to respond on the line send_ws(s): but it I comment that line out , it start to working I expect to send msg to current client periodically , but it won't send any msg

Hamid s k
  • 138
  • 2
  • 6
  • Your code defines `sendDataToLiveSocketPrebiotic`, but doesn't appear to use it anywhere. Is that intentional? – user4815162342 Sep 14 '19 at 09:19
  • @user4815162342 ```sendDataToLiveSocketPrebiotic``` function can be used anywhere outside the WebSocket handler, for example, a coroutine read the serial data and send to live ws client in Java and C++ client id recorded for sending back msg to that client but I don't know how it handled in asyinio or aiohttp lib – Hamid s k Sep 14 '19 at 14:16
  • Are you then looking for a way to invoke `sendDataToLiveSocketPrebiotic` without blocking the handler? The confusing part is that you say "it won't send any msg", but you aren't actually **calling** the function. – user4815162342 Sep 14 '19 at 15:06
  • @user4815162342 I change the code to this, it will run but it stops to working at line `send_ws(s):` – Hamid s k Sep 17 '19 at 09:20
  • @user4815162342 do you have any idea about this code – Hamid s k Sep 24 '19 at 07:39
  • This is now some completely new code, which includes a bunch of JavaScript, so I didn't take the time to study it. Also, it's unclear what it means "stpo working at line `send_ws(s)`" - have you tried putting some prints in `send_ws` to see how far it reaches, or done other kinds of debugging? – user4815162342 Sep 24 '19 at 08:09
  • @user4815162342 if I comment out `await send_ws("helo web site ")` the code working,and this is the whole story here that I can not send back any message outside the WebSocket request handler – Hamid s k Sep 24 '19 at 11:53
  • I understand that, but the next step is to debug the inside of `send_ws`. Note the part of my comment that says: "have you tried putting some prints **in** `send_ws` to see how far it reaches[...]?" – user4815162342 Sep 24 '19 at 12:25
  • @user4815162342 yes, I did some print or log printing inside the `send_ws` function, it seems `await ws.prepare(GlobalRequest)` or ` await ws.send_str(s)` not work at this stage – Hamid s k Sep 25 '19 at 22:25
  • @user4815162342, you know, in C++ WebSocket, I can grab client information from any successfully established WebSocket link, so I can use it in anywhere to send back data to that client, I don't know how can implement with this library – Hamid s k Sep 25 '19 at 22:33
  • I think you're missing `global GlobalWS, GlobalRequest` in `websocket_handler`. Without it you just create local variables which shadow global ones, you're not changing the value of the global vars. – user4815162342 Sep 26 '19 at 08:40
  • Also, you don't need `asyncio.run_coroutine_threadsafe()` if you're in the same thread as the event loop. Use `loop.run_until_complete()` instead. – user4815162342 Sep 26 '19 at 08:41

0 Answers0