lf-lang / playground-lingua-franca

:rocket: Try Lingua Franca now!
Other
16 stars 13 forks source link

WebSocket bind error at ParkingAssist on Linux #57

Open akihitoiwai0912 opened 1 year ago

akihitoiwai0912 commented 1 year ago

The following error happens while ParkingAssist sample runs on my Linux environment. Please advice me how to resolve it. libwebsocket is installed and it works with test program. BrowserUI is working well.

denso@Z0003255709:~/lf-workspace/examples-lingua-franca/C$ bin/ParkingAssist
---- Start execution at time Tue Jul 11 17:45:16 2023
---- plus 352061621 nanoseconds
Environment 0: ---- Spawning 2 workers.
[2023reate_context: LWS: 4.3.99-v4.3.0-277-gf9d1f25a, NET CLI SRV H1 H2 WS SS-JSON-POL ConMon IPv6-absent
[2023/07/11 17:45:16:3523] N: lws_create_context: LWS: 4.3.99-v4.3.0-277-gf9d1f25a, NET CLI SRV H1 H2 WS SS-JSON-POL ConMon IPv6-absent
[2023/07/11 17:45:16:3571] N: __lws_lc_tag:  ++ [wsi|0|pipe] (1)
[2023/07/11 17:45:16:3571] N: __lws_lc_tag:  ++ [vh|0|netlink] (1)
[2023/07/11 17:45:16:3572] N: __lws_lc_tag:  ++ [vh|1|default||240] (2)
[2023/07/11 17:45:16:3572] E: [null wsi]: lws_socket_bind: ERROR on binding fd 6 to port 240 (errno 13)
[2023/07/11 17:45:16:3588] N: __lws_lc_tag:  ++ [wsi|0|pipe] (1)
[2023/07/11 17:45:16:3588] N: __lws_lc_tag:  ++ [vh|0|netlink] (1)
[2023/07/11 17:45:16:3589] W: rops_pt_init_destroy_netlink: netlink bind failed
[2023/07/11 17:45:16:3589] N: __lws_lc_untag:  -- [vh|0|netlink] (0) 14μs
[2023/07/11 17:45:16:3589] N: __lws_lc_tag:  ++ [vh|1|default||241] (1)
[2023/07/11 17:45:16:3589] E: [null wsi]: lws_socket_bind: ERROR on binding fd 8 to port 241 (errno 13)
denso@Z0003255709:~/lf-workspace$ wscat -c ws://websocket-echo.com
Connected (press CTRL+C to quit)
> hi there
< hi there
> are you a happy parrot?
< are you a happy parrot?
edwardalee commented 1 year ago

This kind of error usually arises when some other program is using port 241. In ParkingAssist.lf, there are two lines that select the port to use:

  s = new WebSocketServer(hostport=240, max_clients=1)  // Allow only one client
...
  s = new WebSocketServer(hostport=241, max_clients=1)  // Allow only one client

You could try changing these to a different port, but then the HTML file will also have to change to match. Alternatively, you could find which program is using port 241 and terminate it. A quick google search suggests the following command may reveal which program is using 241:

netstat -anpe | grep "241"
akihitoiwai0912 commented 1 year ago

Thank you for your answer! I tried these methods, but it didn't work. When I looked it up, I found that the cause was the Windows firewall on the host PC. My Linux environment uses Windows Subsystem for Linux (WLS2). Therefore, the Linux network is also managed by Windows Defender, and incorrect ports other than the default are blocked. In this case, WebSocket communication is blocked except for the default port 8000. I actually tested it. Therefore, it should be solved by changing the settings of Windows Defender as follows, but since the Windows PC is a company-provided PC, there is no administrator privilege, and unfortunately, it cannot be changed.

https://learn.microsoft.com/en-us/windows/wsl/troubleshooting#wsl-has-no-network-connection-on-my-work-machine-or-in-an-enterprise-environment

If the default port number is 8000, WebSocket communication can be performed without any problems. I will continue to investigate, but it would be helpful if there are any countermeasures, for example, only port 8000 is used for two reactors.

edwardalee commented 1 year ago

Unfortunately, this application requires two ports, one for the dashboard and one for the sensors, so just changing the default port to 8000 won't be sufficient. I guess an alternative would be to run the LF code on raspberry pi and point your browser to it. That might be better anyway; we could replace the simulated sensors with real ones.

akihitoiwai0912 commented 1 year ago

After changing the Windows network policy and changing the port numbers to 5000 and 5001, it worked fine. However, there is a PlayWaveform error, so I remove it and run it. I have installed ASLA libraries and utilities, but the WSL2 kernel does not recognize the sound card. I'm doing a lot of research, but it's a bit of a hassle.

lhstrh commented 1 year ago

If we want to make it easier to run, we should not rely on low-level platforms for audio, but instead rely on the browser... If we want to get around the local port problem, we could add the option to run the server in a Docker container in the cloud. A student in the project, @byeong-gil, has done this successfully in the past.

lhstrh commented 1 year ago

If you run this on GitPod or Codespaces, the webserver you run should become available through your cloud instance. This means you connect to some remote website at port 8000 and would not have to open up that port to serve something on your local machine... Does this solve the problem, @akihitoiwai0912?

akihitoiwai0912 commented 1 year ago

@lhstrh I've confirmed that you can build with GitPod and codespaces, but I haven't tried remote connectivity to WebSite yet. I understand that the current ParkingAssistant.lf method is to load the ParkingAssistant.html file in a web browser on the local PC, connect to localhost via port8080 using the http protocol, and communicate with the JS program on the html file via WebSocket. What if ParkingAssistant on codespaces accesses the ParkingAssistant.html file of a particular HTTP server? How about starting an HTTP server and accessing the ParkingAssistant.html file like the BrowserUI.lf sample program? In that case, codespaces handles the processing over the network on the cloud instance, which is convenient because users don't have to set up a separate HTTP server. Am I understanding correctly?

lhstrh commented 1 year ago

Right. If you open examples/C/src/browser-ui/BrowserUI.lf in Codespaces or GitPod, and build and run it, a pop-up window should appear in the bottom-right corner with a link to the cloud URL where you can reach the web server running on localhost in the container.

edwardalee commented 1 year ago

I think what @akihitoiwai0912 is asking for is a combination of BrowserUI and ParkingAssist. Currently, in BrowserAssist, when you visit the web server it starts, the web server serves the HTML code for the web page you see, which includes all the JS scripts. ParkingAssist, on the other hand, starts a server that only listens for websocket connections. It does not serve any HTML or JS code.

These two mechanisms could be easily combined.

akihitoiwai0912 commented 1 year ago

@edwardalee Thank you for your explanation! I understood the mechanism. Let me confirm the meaning of your last sentence. Does this mean that ParkingAssist.if can be easily modified to combine with BrowserUI? If so, it would be helpful if you could change it like that.

edwardalee commented 1 year ago

I have pushed changes to playground-lingua-franca in the browser branch that combines the web socket and web server in the ParkingAssist example. Unfortunately, I can't merge this main because CI is broken in this repo, but I guess you can just check out the browser branch for now. @lhstrh : Any idea how to get CI to work so we can merge this rather simple update?

lhstrh commented 1 year ago

CI isn't broken; the third-party action that is being used to check our docker image failed and passed after a re-run. I've merged the PR.

akihitoiwai0912 commented 1 year ago

Thank you for your modification. I tested new codes on multi platforms. Here are results for each platform.

Mac:

Linux(WSL2):

Codespaces:

edwardalee commented 1 year ago

Unfortunately, port 5000 doesn't work for me, so I guess there is no choice here that will work for everyone.