some webdev basic questions for a noob.
background: I have a javascript client that uses the websocket protocol, and a good old java server, which I'm perfectly able to interact with via telnet. I want them to be able to communicate to each other locally (passing strings would suffice).
For that, I definitely don't want to make deep changes in the client. I tried to adapt the server to websocket following this guide before that, and even passed the handshake but it got pretty messy.
So at this point I believe that the best way to deal with this would be to serve through a TCP->WebSocket proxy like websockify. If I got the explanation right, it would "wrap" the server's process, opening the "upgraded" connection in a new port. And the websocket client should be able to directly speak to the server through that port. But I've been trying to implement this with different approaches without success, therefore my questions:
Is there a better way to deal with this problem? (that would explain google's sparseness, I can imagine this happens very often!)
If "wrapping" is the best way and I got it right, how to implement it?
Implementation - edited: For the sake of testing, I've tried to build a simple echo server:
I'm running the very simple command line echo server suggested in this post: ncat -l 2000 -k -c xargs -n1 echo. Talking to it via telnet localhost 2000 returns the desired echo. So far so good.
I installed websockify using apt-get,and run it as follows: websockify 2023: 2000, this should open the same server via a websocket connection on port 2023.
At this point I'm still able to comunicate via telnet localhost 2000, but I'm not having that much luck with port 2023. This is what I tried so far:
Downloaded the telsocket binary, and called ./telsocket -url ws://127.0.0.1:2023. Response: errrr dial tcp 127.0.0.1:2023: connection refused
Cloned wssh (a command line shell for websocket), which seems very promising. I was able to install it, but running wssh -l localhost:2023 returns NameError: name 'PROTOCOL_SSLv3' is not defined. Apparently some problems with gevent (didn't look much further into that).
Tested the several examples in websockify's repo, like wstelnet, or the ones in tests. All of them got me a code 400, message Invalid protocol selected.
Follow-up - edited: Diving deeper into the websock.js and wstelnet.js files, I was able to get more specific results by issuing the following into the JS console:
ws = new Websock()
ws.open("ws://127.0.0.1:2023", "binary") // connects, proxy says: connecting to: :2000, Plain non-SSL (ws://) WebSocket connection, Version hybi-13, base64: 'False'
ws.send_string("hello server") // send and wait for echo
ws.get_rQ() // empty??
So, as you can see, I'm able to establish the connection, but still don't get an echo. The mistake might be as well in the server's side since every tool I tried is failing. Help! D:
Remarks: Since it is intended to work locally, I wouldn't care having either ws or wss. I also don't have a preferred way to do this as long as it is viable and works. In case it is relevant, I'm on Ubuntu15.10 + Firefox47.0
finally, I got the TCP echo server communicating with websockify's websocket telnet emulator through websockify's proxy. This is how:
run the echo server ncat -l 2000 -k -c 'xargs -n1 echo echoServer received'
in a separate process, run the proxy: websockify 2023 :2000
clone the repo: git clone https://github.com/novnc/websockify.git, and make the following changes to wstelnet.js:
3.1 changing the line ws.open(uri) to ws.open(uri, "binary") allowed to overcome the code 400 problem.
3.2 in the definition of do_recv (this is a permalink), add the following line after the initial var statement: arr = Array.from(arr); this is a conversion to Array since Uint8Array didn't apparently support the shift method.
open wstelnet.html with firefox, select Host: localhost, Port: 2023, no encryption, press Connect and type into the black field.
The screen should reply with echoServer received: <YOUR_MESSAGE>. hurray!
Related
I am working on an application that uses an express server to reach out to an API to fetch data. In our organisation outbound traffic requires a proxy which I have supplier to axios like below (not the real one):
let response = await axios.get(endpointUrl, {
proxy: {
host: "123.45.678.90",
port: 0000,
},
})
Passing various URLs into the axios get function returns varied results, with the following URLs returning a result:
https://www.boredapi.com/api/activity
https://api.ipify.org?format=json
https://jsonplaceholder.typicode.com/todos/1
Whereas the following URLs are returning an ECONNRESET error almost instantly:
https://api.publicapis.org/entries
https://randomuser.me/api/
https://reqres.in/api/users
I can't see any pattern between the URLs that are/are not working so wondered if a fresh set of eyes could spot the trait in them? It's important to note that all these URLs return successfully in the browser, just through this axios call being the problem.
To add to the mystery, the URLs that do work work on my machine, do work on a machine outside our organisation - so potentially a clue there?
Any help/guidance of course would be appreciated, thank you.
This error simply means that the other party closed the connection in a way that was probably not normal (or perhaps in a hurry).
For example, a socket connection may be closed by the other party abruptly for various reasons or you may have lost your wifi signal while running your application. You will then see this error/exception on your end.
What could also be the case: at random times, the other side is overloaded and simply kills the connection as a result. If that's the case, depends on what you're connecting to exactly…
Solution - This is happening because you are not listening to/handling the 'error' event. To fix this, you need to implement a listener that can handle such errors.
If the URL that work on your machine also work outside your organization and the other don't, it is most likely a problem with your proxy.
Some proxies might have configurations that makes them remove headers or change the request in a way that the target does not receive it as intended.
I also encountered a problem with axios and proxies once. I had to switch libs to make it work. To be sure, I would recommand using a lib like "request" (deprecated) juste to make sure it is not a problem with axios. There are multiple open issues on the axios repository for proxy issues.
ECONNRESET is likely occurring either because the proxy runs into some sort of error and drops the connection or the target host finds something wrong with the incoming connection and decides to immediately drop it.
That target host may either be finding a problem because of the proxy or it may be expecting something in the request that it finds is missing.
Since you have evidence that all the requests work fine when running from a different location (not through your proxy) and I can confirm that your code works fine from my location (also not running through your proxy), it definitely seems like the evidence points at your proxy as causing some problem in some requests.
One way to debug proxy issues like this is to run a request through the proxy that ends up going to some server you can debug on and see exactly what the proxy has done to the incoming request, compared to a request to that same host that doesn't go through the proxy. That will hopefully highlight some difference that you can then test to see if that's causing the problem and then eventually work on the configuration of the proxy to correct.
Zup coders. I've implemented a simple website that uses Web Sockets PHP (Consik Yii2 solution: https://github.com/consik/yii2-websocket) vs JS (Html5).
Everything is working fine, I only have one issue with my solution, making sure the server is always alive.
I though about saving the WebSocket Instance into Cache and throw a cron that checks the state of the instance. I installed memcached and found out that i can´t save a serialized version of the WebSocket Server instance. ¿Is this a good solution? ¿Would Redis Caché fix this?
I also thought about using client side JS to react to "Error during WebSocket handshake: Unexpected response code: 200" but i can't seem to get it working. I also don't like making the URL that starts websockets public.
Ex:
connect = function(){
websocket = new WebSocket(webSocketURL);
websocket.onerror = function(){
$.get( "/startWebSocketServer",
function(data){
connect();
}
);
};
};
connect();
Thanks!
I think that as matter of fact you need a process supervisor who takes care to "supervise" your server process and do actions in response of process/system events like crash, restart etc..
There are several solutions for each case (standard OS implementations, personal preferences, fit your need), here a list http://without-systemd.org/wiki/index.php/Init , Service managers section could best fit your needs.
Supervisord is easy to setup and configure, it could be a good start thanks to a good bunch of examples around the net.
Solution 1: using a cache could not be the most orthodox way to implement a custom-made supervisor.
Solution 2: is legit as long as it informs user about a problem, the call to an exposed endpoint to start a service IMHO could be a security flaw.
My webapp uses JSP / JavaScript/ google visualization, and runs on Tomcat 7 on a 64bit windows server with enough resources dedicated to this app.It is still under testing, so, I have control over the load.
The problem is when I work from device at same network of the server, everything works fine. But when I work from device from different network with a request took a long time (more than 6 minutes) I get Service Unavailable [503] message after 6 minutes of waiting while processing in the server is going on and completed successfully. I checked the Tomcat logs but i couldn't find any thing every thing seems to be work fine. I tried different solutions but non of them worked with me:
Increase Tomcat's connector timeout.
Increase the Tomcat RAM.
Disable the server firewall
Try different browsers
Adjust the request timeout from the browser.
I experimented by setting Tomcat's Connector properties in conf/server.xml. I played around with all combinations and ranges of connectionTimeout and keepAliveTimeout.
The final configuration is:
<Connector port="80" protocol="HTTP/1.1"
address="0.0.0.0"
connectionTimeout="3600000"
redirectPort="8443" />
I'm wondering if anybody else has run into such a problem, and how they solved it.
I think you server.xml is having wrong data . Change connector port from 80 to 8080 it always allow four digit and start from 8080 not sure . please update as below
<Connector port="8080" protocol="HTTP/1.1"
address="0.0.0.0"
connectionTimeout="3600000"
redirectPort="8443" />
503 Service Unavailable
The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. The implication is that this is a temporary condition which will be alleviated after some delay. If known, the length of the delay MAY be indicated in a Retry-After header. If no Retry-After is given, the client SHOULD handle the response as it would for a 500 response.
Note: The existence of the 503 status code does not imply that a
server must use it when becoming overloaded. Some servers may wish
to simply refuse the connection.click here for more information
let me know if you face any issue
What I want to do is simple in theory, but I cannot quite get it to work.
I wrote a simple node.js script that uses the request package to asynchronously fetch some data, parse it, and spit it out as html. I wanted to integrate this script in my client's php and apache based website which is on a shared host, and ran into some snags:
There is no mod_proxy, so I can't simply run my node script as a server and proxy through Apache
I don't want to run node on port 80 and proxy to apache from node. It's just way too much overkill for what I need to do, and would introduce too many headaches for me. My particular shared host is known to have trouble keeping node server instances up, and I can't justify potential downtime just for this script to run.
I tried the node-cgi package but it didn't work for me. I got errors about internal node methods not existing, I think this package is just out of date.
So what I have landed on is trying to simply call node from PHP. My whole index.php file is:
<?php
header("Content-Type: text/html");
exec("node beerlist.nd", $output);
echo implode('', $output);
When I execute php index.php on the command line, I get my expected output, however, when I try to access this from the browser, I get nothing ie Content-Length: 0. Why?
I thought maybe it had to do with the async nature of my node script but it seems like the process stays alive until it finishes all the async calls. So shouldn't my php snippet send the output to the browser without any trouble? What am I missing here?
Edit: This gist of my node script is
var req = require('request')
req("http://mywebsite.com", function(err, resp, body) {
var output = // pull some interesting pieces out of the whole body
console.log(output);
});
The generation of my output variable is not central to the issue here. The relevant parts are that I use request to make an asynchronous call and use console.log to output my results... maybe this is a problem?
I suppose Apache user doesn't know what node command is. If I'm right try to write in php file:
<full path to node> beerlist.nd
instead of
node beerlist.nd
To get full path to node run in terminal which node
I'm trying to determine how to setup a web socket for the first time ever so a working minimal example with static variables (IP address for example instead of getservbyname) will help me understand what is flowing where.
I want to do this the right way so no frameworks or addons for both the client and the server. I want to use PHP's native web sockets as described here though without over-complicating things with in-depth classes...
http://www.php.net/manual/en/intro.sockets.php
I've already put together some basic JavaScript...
window.onload = function(e)
{
if ('WebSocket' in window)
{
var socket = new WebSocket('ws://'+path.split('http://')[1]+'mail/');
socket.onopen = function () {alert('Web Socket: connected.');}
socket.onmessage = function (event) {alert('Web Socket: '+event.data);}
}
}
It's the PHP part that I'm not really sure about. Presuming we have a blank PHP file...
If necessary how do I determine if my server's PHP install has this socket functionality already available?
Is the request essentially handled as a GET or POST request in
example?
Do I need to worry about the port numbers? e.g. if
($_SERVER['SERVER_PORT']=='8080')
How do I return a basic message on the initial connection?
How do I return a basic message say, five seconds later?
It's not that simple to create a simple example, I'm afraid.
First of all you need to check in php configuration if the server is configured for sockets with the setting enable-sockets
Then you need to implement (or find) a websocket server that at least follows the Hybi10 specification (https://datatracker.ietf.org/doc/html/draft-ietf-hybi-thewebsocketprotocol-10) of websockets. If you find the "magic number" 258EAFA5-E914-47DA-95CA-C5AB0DC85B11 in the code for the header, you can be sure it does follow at least Hybi06 ...
Finally, you need to have access to an admin console on the server in order to execute the PHP websocket server using php -q server.php
EDIT: This is the one I've been using a year ago ... it might still work as expected with current browsers supporting Websockets: http://code.google.com/p/phpwebsocket/source/browse/trunk/+phpwebsocket/?r=5