Erlang websocket client with cowboy server - websocket

Im trying to use this websocket client library but with little success.
Erlang websocket client
If someone used this library to build a client talking to a remote server, how were you able to send messages ?
The basic usage shows to call this to inititate a connection,
websocket_client:start_link("wss://echo.websocket.org", ?MODULE, []).
and cast/2 to send a message to a remote server.
websocket_client:cast(self(), {text, <<"message 1">>}).
However, if I try to use the same function else where in the code to send a text/binary frame to remote server, its not helping.
Is there anything that Im missing ?
Thanks!

Keep in mind that the first parameter to websocket_client:cast/2 must be the pid for the websocket_client process. You can get the pid from the start_link call, e.g.:
{ok, Pid} = websocket_client:start_link("wss://echo.websocket.org", ?MODULE, []).
And to cast a message to the remote server:
websocket_client:cast(Pid, {text, <<"message 1">>}).
In the example code for the websocket_client project cast is called from within the init function, in this case they can use self() since the init function is actually executed by the websocket client process.
Similarly if you are calling cast from within your websocket_handle/websocket_info callback functions you can use self() since those are also called by the websocket client process.

Related

Elixir erlang :ftp.send got stuck

I use Erlang ftp lib in my elixir project to send file to ftp server.
I call send function :ftp.send(pid, '#{local_path}', '#{remote_path}') to upload file to ftp server.
Most of the time it uploads files successfully, but it sometimes stuck here, not moving to the next line.
According to the docs it should return :ok or {:error, reason}, but simply stuck at :ftp.send.
Can anyone give me suggestion? I am not familiar with Erlang.
Version: Elixir 1.7.3 (compiled with Erlang/OTP 21)
ftp module has two types of timeout, both set during the initialization of ftp service.
Here is an excerpt from the documentation:
{timeout, Timeout}
Connection time-out. Default is 60000 (milliseconds).
{dtimeout, DTimeout}
Data connect time-out. The time the client waits for the server to connect to the data socket. Default is infinity.
Data connect time-out has a default value of infinity, meaning it’d be hang up if there are some network issues. To overcome the problem, I’d suggest you set this value to somewhat meaningful and handle timeouts in your application appropriately.
{:ok, pid} = :ftp.start_service(
host: '...', timeout: 30_000, dtimeout: 10_000
)
:ftp.send(pid, '#{local_path}', '#{remote_path}')

Can Windows Socket #10060 error (WSAETIMEDOUT - An attempt to connect timed out without establishing a connection) be a programming error at all?

I have Delphi application that uses Indy HTTP components (that uses Windows socket). And from time to time I am receiving #10060 socket error (WSAETIMEDOUT - An attempt to connect timed out without establishing a connection) upon execution of Indy procedure:
CheckForSocketError(IdWinsock2.Connect(ASocket, #LAddr, SizeOf(LAddr)));
...
connect : TconnectProc;
...
TconnectProc = function ( const s: TSocket; const name: PSockAddr; const namelen: Integer): Integer; stdcall;
Actually all this is just wrap around Windows connect function https://learn.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-connect that gives error and message WSAETIMEDOUT. So - my question is - can this be programming error at all? Even if I have server running on the other computer and even that server has trouble serving request, even in such cases the low level connect should execute normally, if the server can not serve the GET/POST request, then, of course, the errors should be but those errors should spring in only during execution of other Socket functions not in the connect function, isn't so?
I am trying to solve my problem https://serverfault.com/questions/973648/is-it-possible-that-unencrypted-traffic-can-cause-windows-socket-10057-10060?noredirect=1#comment1266907_973648 and now I am seeking whats happening in my code.
My server side code is very simple - it is just TIdHttpServer component with implemented (I provide event name only here):
MyForm.IdHTTPServerCommandGet(AContext: TIdContext;
ARequestInfo: TIdHTTPRequestInfo; AResponseInfo: TIdHTTPResponseInfo);
So - what can be worng with my implemention, what can lead to the appearance of WSAETIMEDOUT for connect? Yes, my procedure can be long sometimes, but it for years it returned the answer sucessfully and there were no communication errors. And I guess, that connect function can even not depend (does not use/raise) OnCommandGet event, so, I have no control how the server side handles socket connect function from the client?
It may be possible that this is connected with TCP (not HTTP) keepalive, maybe some Windows updates have reduced client-side settings of Windows TCP keepalive for the clients and now this manifests as such error.
Indy TCP clients, like TIdHTTP, have a public ConnectTimeout property, which is set to 0 (infinite) by default. If no timeout is specified, a hard-coded 2 minute timeout is used if the client's TIdTCPClient.Connect() method is called in the main UI thread and TIdAntiFreeze is active, otherwise no timeout is used.
If a timeout is used, Indy calls Winsock's connect() function in a worker thread and waits for that thread to terminate. If Indy's timeout elapses, the socket is closed to abort the connect(), and then EIdConnectTimeout is raised to the caller. If connect() exits before Indy's timeout elapses, an exception is raised to the caller only if connect() failed.
If no timeout is used, Indy calls Winsock's connect() directly, waits for it to exit on its own accord, and then raises an exception only if failed.
So, the ONLY way you can get a WSATIMEDOUT error from Indy when it is calling Winsock's connect() function is if Winsock itself timed out internally before Indy's own timeout elapses. That does not necessarily indicate a problem in your code. It just means that the Host you are trying to connect to is simply not reachable at that moment in time. If the server were reachable, but could not accept your connection, you would get a different error, such as WSAECONNREFUSED.
If your server is behind a firewall or router, make sure it is not blocking connections from reaching your server. Try running a packet sniffer on the server machine, such as WireShark, and make sure the 3-way TCP handshake from TIdHTTP is reaching the server machine correctly.

How can I write a WebSocket client in Julia?

I would like to connect to a WebSocket via Julia. I attempted to get an echo response from wss://echo.websocket.org, but it does not seem to respond as I would have expected it to. Interestingly, it does seem to connect, though, whereas an invalid address will not.
julia> client = connect("echo.websocket.org", 443)
TCPSocket(open, 0 bytes waiting)
julia> println(client, "Hello, world!")
julia> readline(client)
""
Is it possible to accomplish this?
There is now a specific library https://github.com/JuliaWeb/WebSockets.jl. Examples of how to use it are provided in examples/chat.jl and examples/chat-client.html.
Web socket clients cannot be implemented by opening a socket and reading and writing directly to it. There is a reasonably complicated protocol that needs to be implemented. Further, a websocket client is meant to receive push request, and hence needs some way to handle them asynchronously.
There is a websocket client library implemented in Julia: https://github.com/dandeliondeathray/DandelionWebSockets.jl
To install it, do: Pkg.clone("https://github.com/dandeliondeathray/DandelionWebSockets.jl")
To use it involves defining event handlers for network events. Please see here for an example using echo: https://github.com/dandeliondeathray/DandelionWebSockets.jl/blob/b23307f360ef0b62e3064c6b1484599eb660f63f/examples/echo.jl

Connecting two WebSocket servers to eachother

I have two WebSocket servers that can communicate wonderfully with a client. They are on two separate machines, implemented in Java and running inside WildFly8 webservers. What I need them to do now is communicate with each other. That means: client sends message to server 1, server 1 sends message to server 2, receives the reply and sends it back to client.
The servers run on different apps in OpenShift and I need them to use websockets. Or some other type of communication, but I haven't managed to find anything that actually works so far (RMI or normal socket connections won't work).
What I basically tried to do is use the same code from the client within the onMessage method of the first server. Something like this:
#OnMessage
public void message(Session session, String msg){
...
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
Session NewSession = container.connectToServer(Client.class, URI.create(URL));
NewSession.getBasicRemote().sendText("Routed :" + input);
...
}
However, the server does not connect to the other server and I don't know why.
Any suggestions?
Thank you!
Put connectToServer inside a try {} catch, you might get an error. Log it.
I'm struggling to do exactly the same things (2 websocket servers, Wildfly 8), and I get a permission denied error. See my post here:
https://stackoverflow.com/questions/30966757/java-server-to-server-communication-with-websockets-permission-denied

Is there a way to invoke the gevent-socketio BaseNamespace.emit server side

Is there a way to invoke the gevent-socketio BaseNamespace.emit on the server side since it uses environ['socketio'] to get the socket from the request.environ. How I can generate new virtual socket or emualate somehow the environ['socketio'] on the server so I can use it to invoke the gevent-socketio BaseNamespace class (for emitting a message for example).
The idea behind this is that the server itself would be able to broadcast messages on a fixed period.
Thanks

Resources