Socket.io 404es on Heroku on every port I tried - heroku

I have the app running and it doesn't find socket.io and gives me 404.
this is the client:
<script src="http://game-test-1.herokuapp.com/socket.io/socket.io.js"></script>
<script>var socket = io.connect('http://game-test-1.herokuapp.com');</script>
and this is the server:
var express = require('express'),
routes = require('./routes'),
user = require('./routes/user'),
http = require('http'),
path = require('path'),
express = require("express"),
app = express(),
server = http.createServer(app),
io = require('socket.io').listen(server);
server.listen(80);
I tried changing the ports and doing http://game-test-1.herokuapp.com:81/... but that gave me an error
How do I link socket.io correctly?

Heroku requires that your application listens on a port of Heroku's choosing. Heroku will tell your application this port when it launches your application, via the PORT environment variable. If you listen on any other port, Heroku will ignore it and will terminate your application after 60 seconds.
Your users' browsers will still use ports 80 for HTTP traffic and 443 for HTTPS traffic. Heroku's routing layer, which is in-between the user's browser and your application, will send the HTTP traffic through to your application at the port Heroku designated for your application.

Heroku Dev Center has a guide on using socket.io on Heroku. In particular, you'll need this bit of config:
// assuming io is the Socket.IO server object
io.configure(function () {
io.set("transports", ["xhr-polling"]);
io.set("polling duration", 10);
});

This is because Heroku does not support Websockets at this time (to the best of my knowledge) In order to use socket.io you need to force it to fallback to an xhr long-polling approach.

Related

How to deploy and interact with a rust websocket?

I'm a beginner in Rust and WebSockets and I'm trying to deploy on Heroku a little chat backend I wrote (everything works on localhost). The build went well and I can see the app is running, and I'm now trying to connect to the WebSocket from a local HTML/Javascript frontend, but it is not working.
Here is my code creating the WebSocket on my rust server on Heroku (using the tungstenite WebSocket crate):
async fn main() -> Result<(), IoError> {
let port = env::var("PORT").unwrap_or_else(|_| "8080".to_string());
let addr = format!("0.0.0.0:{}", port);
// Create the event loop and TCP listener we'll accept connections on.
let try_socket = TcpListener::bind(&addr).await;
let listener = try_socket.expect("Failed to bind");
println!("Listening on: {}", addr);
and here is the code in my Javascript file that tries to connect to that WebSocket:
var ws = new WebSocket("wss://https://myappname.herokuapp.com/");
My web client gets the following error in the console:
WebSocket connection to 'wss://https//rocky-wave-51234.herokuapp.com/' failed
I searched to find the answer to my issue but unfortunately didn't find a fix so far. I've found hints that I might have to create an HTTP server first in my backend and then upgrade it to a WebSocket, but I can't find a resource on how to do that and don't even know if this is in fact the answer to my problem. Help would be greatly appreciated, thanks!
I think your mistake is the URL you use:
"wss://https://myappname.herokuapp.com/"
A URL usually starts with <protocol>://. The relevant protocols here are:
http - unencrypted hypertext
https - encrypted hypertext
ws - unencrypted websocket
wss - encrypted websocket
So if your URL is an encrypted websocket, it should start only with wss://, a connection cannot have multiple protocols at once:
"wss://myappname.herokuapp.com/"

How to use Traefik for WebSocket backend

I am trying to configure Traefik for a WebSocket app, I just try with a simple WS app on docker: https://hub.docker.com/r/jmalloc/echo-server/
To test it I use Chrome SimpleWebSocketClient, so if I use the IP:Port of the app it works fine. If I add the Traefik DNS it fails, I just try with other WS server and clients and fails too, so it would be something of Traefik.
I just try with Traefik versions:
-v1.3.0/raclette
-v1.2.3/morbier
Those are my Traefik rules:
[backends.ws-test-backend]
[backends.ws-test-backend.LoadBalancer]
method = "drr"
[backends.ws-test-backend.servers.server1]
url = "ws://172.16.8.231:3000"
[frontends.ws-test-frontend]
backend = "ws-test-backend"
passHostHeader = true
entrypoints = ["http","https","ws", "wss"]
[frontends.ws-test-frontend.routes.manager]
rule = "Host:ws-test.ikcloud.ikerlan.es"
What could it be wrong?
Any recommended reverse proxy for doing this?
You need to enable sticky session for your ws connections, otherwise it will be reconnecting all the time.
[backends]
[backends.backend1]
# Enable sticky session
[backends.backend1.loadbalancer.stickiness]

using port 80 in Websocket server

I am developing a chat server in php using html 5 and Websocket
I want to connect the websocket to a subdomain with port 80 using something like the following code:
var ws = new WebSocket("ws://subdomain.mydomain.com:80");
How can my Apache sever listen to port 80.Is it even possible or not.
If it's not possible , is there a way by which i can forward data from port 80 to another port(ex:8080)
The reason why i am doing so is that i wanna use the websocket beside proxy.
Is there any other solution handling this issue .

connecting autobahn websocket server to crossbar.io router

I have an application that connects to a web page that sends and receives text strings over a websocket on port 1234. I do not have access to the front end code, so I cannot change the HTML front end code.
I created an autobahn server with a class derived from WebSocketServer protocol that communicates with the web page over port 1234. This works and I am able to send and receive text to the front end.
However, I need to process incoming data and would like to publish the received data to a crossbar.io container through the router on port 8080 (or any other port). The port to the web browser is fixed at 1234.
It there a way for me to "plug in " the autobahn websocket server into the crossbar router or is there an alternative way to create a websocket server that will allow me to to send and receive the text on port 1234 and at the same time participate in pub/sub and RPC with the crossbar router?
I am assuming you are using Python. If you are not, the answer should still be the same, but depending on the language/library and its implementation the answer can change.
From what you are saying, it does not sound like you really need a "plug in". Crossbar does have these under the description of router components. But unless you really need to attach a Python instance directly to the router either for performance or otherwise, I would recommend keeping your application off the router. It would work perfectly fine as a stand alone instance especially if it is on the same machine where the WAMP router is located where the packets would only require to communicate over loopback (which is VERY fast).
Given that you are using Python:
You can use your WebSocketServer and a WampApplicationServer together. The little hiccup you might run into is starting them up properly. In either scenario Python2.x with twisted or Python3.4 with Asyncio you can only start the reactor/event loop once or an error will ensue. (Both Twisted and Asyncio have the same basic concept) In Asyncio you will get RuntimeError: Event loop is running. if you attempt to start the event loop twice. Twisted has a similar error. Using the ApplicationRunner in twisted, there is an option (second argument in run) not to start up the reactor which you can use after the reactor is already running. In Asyncio, there is no such option, the only way I found out how to do it is to inherit the Application runner and overwrite the run method to start the session to be started as a task. Also, be warned that threads do not cooperate with either event loop unless properly wrapped.
Once you have the two connections set up in one instance you can do whatever you want with the data.
Thanks for the idea, and the problems you mention are exactly what I encountered. I did find a solution however, and thanks to the flexibility of crossbar, created a JavaScript guest that allows me to do exactly what I need. Here is the code:
// crossbar setup
var autobahn = require('autobahn');
var connection = new autobahn.Connection({
url: 'ws://127.0.0.1:8080/ws',
realm: 'realm1'
}
);
// Websocket to Scratch setup
// pull in the required node packages and assign variables for the entities
var WebSocketServer = require('websocket').server;
var http = require('http');
var ipPort = 1234; // ip port number for Scratch to use
// this connection is a crossbar connection
connection.onopen = function (session) {
// create an http server that will be used to contain a WebSocket server
var server = http.createServer(function (request, response) {
// We are not processing any HTTP, so this is an empty function. 'server' is a wrapper for the
// WebSocketServer we are going to create below.
});
// Create an IP listener using the http server
server.listen(ipPort, function () {
console.log('Webserver created and listening on port ' + ipPort);
});
// create the WebSocket Server and associate it with the httpServer
var wsServer = new WebSocketServer({
httpServer: server
});
// WebSocket server has been activated and a 'request' message has been received from client websocket
wsServer.on('request', function (request) {
// accept a connection request from Xi4S
//myconnection is the WS connection to Scratch
myconnection = request.accept(null, request.origin); // The server is now 'online'
// Process Xi4S messages
myconnection.on('message', function (message) {
console.log('message received: ' + message.utf8Data);
session.publish('com.serial.data', [message.utf8Data]);
// Process each message type received
myconnection.on('close', function (myconnection) {
console.log('Client closed connection');
boardReset();
});
});
});
};
connection.open();

websocket doesn't get connected

I could connect websocket to the server on my local machine. But when i uploaded the file to a remote ubuntu server, it doesn't work any more.
Server side code(server.php):
$master = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
socket_set_option($master, SOL_SOCKET, SO_REUSEADDR, 1);
socket_bind($master, "127.0.0.1", 80);
socket_listen($master, 20);
client side code:
<script type="text/javascript">
var host = "ws://127.0.0.1:80/server.php";
socket = new WebSocket(host);
</script>
I open the client page from chrome canary version 24, server side didn't get any accepted socket.
I changed the host to "ws://xx.xx.xx.xx:80/server.php" to the real IP address of the server, doesn't work. Also changed the server side socket_bind($master, "127.0.0.1", 80) to real ip, no luck either.
Any one can help me?
Thanks,
Jasmine
My friend, when you write your server. You need to keep it running as a service or just keep it running.
In the case of a php server, you need to run that file from the PHP Cli (php yourfile.php), not from the browser (You can, setting the timeout to 0, but if you close the browser, your server stops working).
I really don't recommend a socket server over PHP. Read more about socket servers with C++ (QT, Berkeley), or Java Socket Servers.
When we are talking about HTML5 Websockets Server, it's different from programming a 'normal' socket server (There are a lot of libraries for PHP that can help you programming a HTML5 Websocket server)
https://github.com/Flynsarmy/PHPWebSocket-Chat
In that link, you can find an example of a chat. There is a file called class.PHPWebSocket.php, include it in your server.php and use that library for the creation of the HTML5 Websocket Server. See the examples, read how it works and how to use the class.PHPWebSocket.php (Take a look at the server.php file inside the examples).
Run the server when you finish it.
Then do:
// ...
var host = "ws://IP.OF.THE.SERVER:port";
socket = new WebSocket(host);
// ...
Read more about socket servers, HTML5 Websockets, and take a look at that class.PHPWebSocket.php utility.
Good Luck My Friend.

Resources