I'm very new to Socket protocol and I'm sure the problem comes from me knowing almost nothing about this. But basically I have a socket on port 5000 on my server and I need to have an angularjs code to listen to this socket. The socket on the server can read whatever I send from another computer (client). But for some reason the angular code can't listen/connect to the socket. Here's what I have right now:
index.html
<html ng-app="MyAwesomeApp">
<head>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/ng-websocket/ng-websocket.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="cnt">
</body>
</html>
and here's the angularjs code:
app.js
var app = angular.module('MyAwesomeApp', ['ngWebsocket']);
app.controller('cnt', function ($websocket) {
var ws = $websocket.$new('ws://localhost:5000');
ws.$on('$open', function () {
ws.$emit('hello', 'world'); // it sends the event 'hello' with data 'world'
})
.$on('test', function (message) { // it listents for 'incoming event'
console.log('something incoming from the server: ' + message);
});
});
and here's the python code that I have for server socket:
#server example
import socket
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.bind(('localhost', 5000))
serversocket.listen(1) # become a server socket, maximum 5 connections
# print "hello"
while True:
connection, address = serversocket.accept()
print address
while True:
buf = connection.recv(16)
if len(buf) > 0:
connection.sendall(buf)
print buf
# break
Most of the angularjs code comes from https://coderwall.com/p/uhqeqg/html5-websocket-with-angularjs
These are the errors that I get in Chrome
ng-websocket.js:122 WebSocket connection to 'ws://localhost:5000/'
failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
and in Firefox:
Firefox can’t establish a connection to the server at
ws://localhost:5000/.
What you are trying to do is not possible. At least not in a way you want to do it.
WebSockets is an application layer protocol, much like HTTP protocol is. Pay attention at ws part of ws://localhost:5000.
On the other side you are using plain BSD sockets. This is just a raw socket for communication between two parties. It needs an to 'have an idea' about what the other side (AngularJS) is 'speaking', i.e. needs to communicate using same protocol. In BSD sockets case it inherently doesn't.
That is why you get:
ng-websocket.js:122 WebSocket connection to 'ws://localhost:5000/'
failed: Error during WebSocket handshake: net::ERR_CONNECTION_RESET
To be able to do this, you will need some asynchronous programming framework with WebSockets protocol built on top of it. One suggestion is Autobahn.
Related
I am developing an app and using the websockets for the server-client communication. The concept is to have the client requesting from the server for messages and a few times the server needs to push some messages to the client (without the latter has requested for them). (I'll use front-end and back-end to describe my app)
The app works when the front-end requests from the back-end but it doesn't for the case where the back-end needs to be the originator of the message (i.e. emit data without the front-end has requested for that). In that case the websocket seems to stall and blocked for a few seconds, until the client disconnects (reason timeout) and connects again. Of course, the topic sent by the back-end/server is never received by the client, i.e. the /non_requested_topic as seen below.
For the BACK-END I am using flask-socketio in PY2.7 and
events_handling.py
#!/usr/bin/env python
from flask import request
from emit_topics import emit_topic
def on_connect():
print("Client {} connected".format(request.sid))
# set the client ID to unrequested.py blah blah
def on_disconnect():
print("Client {} disconnected".format(request.sid))
def on_topic_request(data):
data_rx = "blah blah"
to = request.sid # client
namespace = "my_namespace"
emit_topic(topic_name="/topic_name", data_rx, to, namespace)
emit_topics.py
def emit_topic(topic_name, data, to, namespace):
socket_io.emit(topic_name, data=data, to=to, namespace=namespace)
And then there is a function that calls emit_topic and pushes some data to the client (without the client has requested for them):
unrequested.py
#!/usr/bin/env python
from emit_topics import emit_topic
def function_a(self):
to = self.client_id # client id that is set every time the client connects
namespace = "my_namespace"
data_rx="Msg from the server"
print("Check the client id {}".format(to)) # this matches with the one observed for the ws
emit_topic (topic_name="/non_requested_topic", data_rx, to, namespace)
For the FRONT-END:
There is an HTML file where:
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.4.5/socket.io.min.js"></script>
var socket = io("my_namespace", {'forceNew': true});
var interval_timer;
socket.on('connect', function() {
console.log('Connected to the server');
interval_timer = setInterval(topics_request, 5000);
});
socket.on('disconnect', function() {
console.log('Disconnected from the server');
clearInterval(interval_timer);
});
socket.on("/topic_name", (msg) => {
console.log("/topic_name rx ", msg);
});
socket.on("/non_requested_topic", (msg) => {
console.log("Non requested topic rx ", msg);
});
function topics_request(){
socket.emit("topic_request", {"topic": "/topic_name"}) // some topic name
}
Is a request from the client required first to trigger the /non_requested_topic or is there a way for the client to keep listening to that?
You have several issues with your code.
First of all, Python 2.7 has not been a supported version of Python for Flask-SocketIO for a while. I strong advise you to start using Python 3.
Your use of namespaces in the server is very inconsistent. Your connect and disconnect handlers do not use a namespace. Your on_topic_request function doesn't either. But then the emit_topic function accepts a namespace as an argument, which you set to my_namespace. Why do you use a namespace only when emitting but not when receiving events? Also, namespaces are supposed to start with a slash.
I have a WebSocket server that I am trying to make and I can't figure out why it is not connecting.
index.html(client):
<p id="status">Connecting...</p>
<input id="message" />
<button id="submit">Send</button>
<script>
var s = new WebSocket("wss://StarliteServer.cs641311.repl.run:8000", ["soap", "wamp"]);
s.onopen = function() {
document.getElementById("status").innerHTML="Connected";
}
document.getElementById("submit").addEventListener("click", function() {
s.send(document.getElementById("message").value);
});
s.onmessage = function(e) {
alert(e.data);
}
s.onclose = function(e) {
document.getElementById("status").innerHTML = "ERROR: "+e.code
}
</script>
app.js
var http = require('http');
http.createServer(function(req, res) {
req.onopen = function() {
console.log("OPENING CONNECTION");
res.writeHead(200);
}
req.on('data', function(e) {
res.write(e);
});
req.on('close', function() {
console.log('CONNECTION CLOSED');
});
}).listen(8000);
A websocket client requires a websocket server to connect to. While all webSocket connections do start with a plain http request, the server must then "upgrade" the connection to the webSocket protocol and the server must be able to speak that webSocket protocol. If not, the client will drop the connection since the server fails to support the proper protocol.
There are multiple websocket server libraries for node.js in NPM. Pick one of those and add it to your server. If your server intends to also serve as a regular http server, you can share the same http server with the websocket server. The webSocket server code will examine each incoming request and pick off the ones that show that they represent the initiation of a webSocket connection and it will take them over from there.
To give you an idea what a webSocket server must do, you can see this article on writing websocket servers. I'm not suggesting you write your own (too much time spent on protocol detail), but this will certainly explain why a plain http server won't suffice for a webSocket connection.
I'm trying to connect with signalr hub, but I'm getting the following error in javascript:
WebSocket connection to 'ws://dev:777/signalr/connect?transport=webSockets&clientProtocol=1.5&connectionToken=%2BRUC9XodaU4R3Wn3BSLfhZXxLqeLj9fp4XlLJSsxrc36dFuEo6O9GOIGYMdsgSeswY2DTzzJe9qCe9JnqgjwusbYROxjkY%2B6d9FD4MVpox4FLEqNzCF5Y%2BOqrY5ndNs%2FRl7aOoKIYelpGmerXj4mdw%3D%3D&connectionData=%5B%7B%22name%22%3A%22machinehub%22%7D%5D&tid=5' failed: Error during WebSocket handshake: Unexpected response code: 504
and then in console
Could not connect. Invocation of StartMachine failed. Error: No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.
I'm using such code to invoke my method from hub which:
self.Run = function (action, parameters, callbacks) {
try {
var connection = $.hubConnection();
connection.logging = self.Debug;
var hub = connection.createHubProxy(self.Name);
registerConnectionEvents(connection);
registerEvents(hub, callbacks);
connection.start({ transport: ['webSockets'] })
.done(function () {
self.debug("Now connected!");
hub.invoke.apply(hub, $.merge([action], parameters)).fail(function (error) {
var msg = 'Invocation of ' + action + ' failed. ' + error;
self.debug(msg);
});
})
.fail(function (error) {
var msg = 'Could not connect. Invocation of ' + action + ' failed. ' + error;
self.debug(msg);
});
return true;
}
When I run my MVC5 app with signalr in Visual Studio everything is fine. After publication to IIS8 on windows Server 2012 it can't connect over web sockets in signal r. I tried to turn off both firewalls for testing but with no success. Can you help me resolve that issue? Of course I read everthing on that page https://learn.microsoft.com/en-us/aspnet/signalr/
In order for SignalR to work properly with WebSocket, you must be sure both client and server support WebSocket. If testing locally works fine, then your browser probably already supports it.
Windows Server 2012 supports SignalR, but you need to be sure websockets feature is enabled:
If this is already enabled, then try recycling your Application Pool (or resetting the IIS).
If recycling/resetting is not sufficient, then you might have something else between the server and the client, like a proxy server or another security layer, like a network firewall (which you might don't have access to it), it could exist in an enterprise environment, or in servers hosted in places like Amazon which might be blocking a port.
I have a node.js server and I attached socket.io listener to it. The code is like this.
const server = new Hapi.Server();
server.connection({
"port": config.port
});
let io = socketio(server.listener);
io.on("connection", function(socket) {
console.log("A user connected");
socket.on("disconnect", function(){
console.log("A user disconnected");
});
// receive message from client
socket.on("client-server", function(msg) {
console.log(msg);
});
});
// somewhere to emit message
io.emit("server-client", "server to client message");
Normally I use the standard way to connect to the websocket server. An example is like this:
<!DOCTYPE html>
<html>
<head><title>Hello world</title></head>
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('server-client', function(data) {document.write(data)});
socket.emit('client-server', 'test message');
</script>
<body>Hello world</body>
</html>
It works without issue. Now, my colleague wants to connect to the websocket server from his FME server. Based on his research, the only way he can use to connect to a websocket server is using a url like this:
ws://localhost:3000/websocket
My question is: is there a way to connect to socket.io server listener using this type of string?
If not, is there a way to create a websocket server with ws://host:port url and also attach it to my node.js server?
Or, is there a way to connect to socket.io listener in FME server?
To tell Socket.IO to use WebSocket only, add this on the server:
io.set('transports', ['websocket']);
And on the client add this:
var socket = io({transports: ['websocket']});
Now you can only connect to the WebSocket server using ws protocol.
So I am trying to make some sort of connection between my Java app and my Web app, I looked up websockets and they look really simple and easy to use :). And I created myself a Java Server, which uses the ServerSocket class.
Now the problem is I am able to connect to the server from the web, with the websocket, but I am unable to send data to the server... but when I tried to send data from a Java Client it worked fine... what might be the problem?
My Java/Scala (I followed this tutorial: https://www.tutorialspoint.com/java/java_networking.htm) server:
class Server(val port: Int) extends Thread {
private val serverSocket = new ServerSocket(port)
override def run(): Unit = {
try {
while(true) {
println("Waiting for client on port: " + serverSocket.getLocalPort)
val server = serverSocket.accept()
println(server.getRemoteSocketAddress)
val in = new DataInputStream(server.getInputStream())
println(in.readUTF())
val out = new DataOutputStream(server.getOutputStream())
out.writeUTF("Hello world!")
server.close()
}
} catch {
case s: SocketTimeoutException => println("Connection timed out!");
case e: Exception => e.printStackTrace()
}
}
}
My web js (I followed https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications ):
/**
* Created by samuelkodytek on 20/12/2016.
*/
var conn = new WebSocket('ws://127.0.0.1:8080');
conn.onopen = function(e) {
console.log("Connection established!");
conn.send("Hello!");
};
conn.onmessage = function(e) {
console.log(e.data);
};
A web socket server is not the same thing as a simple socket server. A server that offers web sockets must first offer HTTP or HTTPS services because the web socket is established when a web client sends an HTTP request with an Upgrade option and special fields for establishing the web socket. Even after the web socket is established, the connection still does not behave exactly like a regular socket. The Web Socket protocol uses frames to send or receive data. This is all considerably different from what you seem to expect.
One other thing that you should be aware of is that the browser will enforce the rule that the web socket must come from the same host as the page that is attempting to establish the web socket (the same protocol, address, and TCP port).