I have a node.js socket server using socket.io.
I'm building a firefox addon, where I load a pageworker. The html in the following page is as follows:
<html>
<head>
<script type="text/javascript">
//THIS DOESN'T WORK
var exampleSocket = new WebSocket("ws://someip:port");
exampleSocket.onopen = function (event) {
console.log("socket opened!");
};
//THIS WORKS
var exampleSocketa = new WebSocket("ws://echo.websocket.org");
exampleSocketa.onopen = function (event) {
console.log("socket to echo opened!");
};
</script>
</head>
<body>
</body>
</html>
I can open a websocket to echo.websocket.org, but not my own server. I get a "debug: destroying non-socket.io upgrade" message. I can switch it off with the option: { 'destroy upgrade': false }, but then I see no debug output from server, and no connection is made.
What am I doing wrong? How can I get a socket open to my socket.io server?
So after some more googling, it turns out that I need to require socket.io on the client side. Even though socket.io uses websockets, it prefers talking to itself.
Related
I've been trying to do this but can you connect to another websites their socket.io server? I've been trying to scrape data from a website that uses socket.io for live updates. It would be very handy if this were to be possible.
I'm trying to get live updates from the website https://www.ethercrash.io/ - However I tried the following code and wouldn't get any updates other than a connection;
var io = require('socket.io-client');
var socket = io('https://www.ethercrash.io')
socket.on('connect', function(){
console.log(true);
});
socket.on('msg', function(data) {
console.log('chat message');
});
socket.on('disconnect', function(){
console.log(false);
});
Am I doing something wrong or is this just not possible?
I use the following in all my node.js / express / socket.io projects. Hopefully it helps you out.
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/socket.io/2.2.0/socket.io.js"></script>
<script>
$(document).ready(function() {
// NOTE, I AM FORCING WEBSOCKET TRANSPORT HERE. AND AM NOT ALLOWING
// SOCKET.IO TO FALL BACK TO LONG POLLING FALLBACK,
// SO YOU CAN REMOVE THE TRANSPORTS AND GO WITH SOCKET.IO DEFAULTS
// PORT I'M USING IS 3000 -- SO THE PORT CAN BE IMPORTANT, DEPENDING ON YOUR USASGE
var socket = io.connect("https://MY-SERVER-NAME-HERE.eastus.cloudapp.azure.com:3000", {
secure: true,
transports: ["websocket"],
path: "/socket/socket.io"
});
// EVERY TIME THE NODE.JS SERVER SENDS US 'MESSAGE' WE'LL DISPLAY THAT UPDATED NUMBER IN A DIV
socket.on("message", function(msg) {
document.getElementById("message").innerHTML = msg;
});
});
</script>
</head>
<body style="width: 100%;">
<div id="message" style="text-align: center; width: 100%; font-size: 2em;"></div>
</body>
</html>
You also are depending on that 'other site' (running the socket server) emitting out to either ALL connected clients or to your connection specifically. Unless either of those happen, you will only have a connection with no messages being emitted out (to be read / parsed).
Sockets are really fun to work with and full of potential once you get the hang of it!
I'm having a bit of an issue with websockets. So, I have a Rpi that provides me some data through a socketIO client in a pretty simple way. The following code shows how do I get to get this data:
<!DOCTYPE html>
<html>
<header>
<title>SocketIO test</title>
<script src="http://192.168.5.5:8000/socket.io/socket.io.js"></script>
</header>
<body>
<script type="text/javascript">
var client = io.connect('http://192.168.5.5:8000');
client.on('connect', function() {
console.log('connected');
});
client.on('raw', function(data){
console.log(data);
});
client.on('state', function(data){
console.log(data);
});
</script>
</body>
However, what I need to implement is a little bit more complex. I need to use a Apache server to trait some of the data before it gets to the client side. The following image shows what I attempt to build:
To reach my goal I tried several WebSocket Servers and Client libraries for PHP until I found PHPws, which looks like the best solution for my scenario.
So, I read the examples, I test them and everything went well until I tried to connect to the Rpi with the following code:
require_once("../vendor/autoload.php");
$loop = \React\EventLoop\Factory::create();
$logger = new \Zend\Log\Logger();
$writer = new Zend\Log\Writer\Stream("php://output");
$logger->addWriter($writer);
$client = new \Devristo\Phpws\Client\WebSocket("ws://192.168.5.5:8000", $loop, $logger);
$client->on("connect", function() use ($logger, $client){
$logger->notice("Or we can use the connect event!");
$client->send("Hello world!");
});
$client->on("raw", function($message) use ($client, $logger){
$logger->notice("Got message: ".$message->getData());
$client->close();
});
$client->open()->then(function() use($logger, $client){
$logger->notice("We can use a promise to determine when the socket has been connected!");
});
$loop->run();
I've more or less taken this example from Devristo's github.
From the server side, the execution of the program is not throwing any error or message.
Is it possible to build what I want to build here with PHPws?
If so, am I connecting properly to de Rpi server with PHPws sample code shown?
It is possible :
[Node] Socket Server (This would be your RPi)
Simple socket.io server in node to check for a
(success) client connection event.
var io = require('socket.io')(1337);
io.on("connection",function(socket){console.log("[+] client",socket.id);})
[PHP] Socket Client
Using Elephant.IO we setup a client (Client Example for Socket.IO v2.0)
<?php
use ElephantIO\Client;
use ElephantIO\Engine\SocketIO\Version2X;
require __DIR__ . '/vendor/autoload.php';
$client = new Client(new Version2X('http://localhost:1337', [
'headers' => [
'X-My-Header: websocket rocks',
'Authorization: Bearer 12b3c4d5e6f7g8h9i'
]
]));
$client->initialize();
$client->emit('broadcast', ['foo' => 'bar']);
$client->close();
With this simple Client/Server example you will see the 'on connection' event in the node server when the browser opens the client.php
I've wrote a simple node.js app by socket.io some weeks ago. My program is fine on my PC but when i tried to run it on my laptop. I faced a really weird error on my console.
note that I'm running node on 127.0.0.1:2324. I don't know what is that ip (0.0.9.20) on the chrome console.
Again, my code is correct cause it's working fine on my PC.
And I get this on my cmd:
my paint.html code is something like this:
<script src="http://127.0.0.1/node/paint/js/jquery.js"></script>
<script src="http://127.0.0.1/node/paint/js/cursor.js"></script>
<script src="http://127.0.0.1/node/paint/js/controllers.js"></script>
<script src="http://127.0.0.1/node/paint/js/core.js"></script>
<script src="http://127.0.0.1:2324/socket.io/socket.io.js"></script>
<link href="http://127.0.0.1/node/paint/css/style.css" rel="stylesheet" />
core.js:
// broadcat function
function broadcast(data)
{
var socketio = io.connect(serverPort);
socketio.emit("message_to_server", { pen : data});
}
// receive data from server
var socketio = io.connect(serverPort);
socketio.on("message_to_client", function(data)
{
var res_brush = data['pen'];
var brush_data_rec = res_brush['pen'].split('|');
draw(brush_data_rec[0],
brush_data_rec[1],
brush_data_rec[2],
brush_data_rec[3],
brush_data_rec[4],
brush_data_rec[5],
brush_data_rec[6]);
});
update:
You should explicitly specify the target hostname on the client to connect to to avoid confusing the client on which address to connect to. There's also a cleaner way to specify a target port.
var socket = io.connect('http://localhost/', {
'port': 8080,
'transports': ['websockets']
});
This is my first time with node js. I am trying to get the client to connect to the server and maintain the connection without closure.
This is all hosted in an ubuntu server edition hosted in a virtualbox.
I had checked that the server is actually listening to the port 5000 using
netstat -ant
Websockets is also available on my browser.
I get the following output with error
Echo server dot come
192.168.1.107
node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: EPIPE, Broken pipe
at Socket._writeImpl (net.js:159:14)
at Socket._writeOut (net.js:450:25)
at Socket.write (net.js:377:17)
at Socket.ondata (stream.js:36:26)
at Socket.emit (events.js:81:20)
at Socket._onReadable (net.js:678:14)
at IOWatcher.onReadable [as callback] (net.js:177:10)
and if i call socket.end() on the server on connection event handler i get a disconnecting client. My question is how to establish a stable connection using this code, what do i have to change or i am doing wrong here? pulling my hair out - thanks in advance!
HTML CODE
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Strict//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Test RS Server (built over nodejs)</title>
<link rel="stylesheet" href="style.css"></link>
<script src="jquery.min.js" ></script>
<script src="client.js" ></script>
</head>
<body>
<label>Message</label>
<input type="text" id="message_box"></input>
<input type="button" id="submit_btn" value="Send"></input>
<div style="clear:both;"/>
<label>Output</label>
<textarea rows="10" cols="100" id="output_box"></textarea>
</body>
</html>
CLIENT JS
var message_box;
var output_box;
var submit_btn;
var url = "wss://192.168.1.107:5000";
var socket;
function createListeners() {
if ("WebSocket" in window) {
output_box.html("Supports sockets.");
socket= new WebSocket(url);
socket.onopen= function() {
socket.send("con opened");
output_box.html("Connection opened.");
};
socket.onmessage= function(response) {
// alert('got reply '+s);
console.log(response);
output_box.html(response);
};
socket.onclose = function() {
// websocket is closed.
output_box.html("Connection is closed...");
};
submit_btn.click(function(e) {
socket.send(message_box.val());
});
} else {
output_box.html("doesnt support sockets");
};
};
$(document).ready(function() {
message_box = $("#message_box");
output_box = $("#output_box");
submit_btn = $("#submit_btn");
createListeners();
});
SERVER JS CODE
var net = require('net');
var server = net.createServer(function (socket) {
socket.write('server says this\r\n');
socket.pipe(socket);
});
server.on('connection', function(socket) {
socket.write("Echo server dot come\r\n"+socket.address().address);
console.log("Echo server dot come\r\n"+socket.address().address);
// socket.end();
socket.pipe(socket);
});
server.listen(5000);
You are trying to use WebScoket client with simple TCP server. This is a different protocols. You need to setup WebSocket server to make it work. You can use websocket module to do that. Look at the server example code here.
I'm trying to work the Redis Cookbook example:
var http = require('http'),
io = require('socket.io')
fs = require('fs'),
redis = require('redis'),
rc = redis.createClient(9189, "pike.redistogo.com");
rc.auth("passwd", function() {
console.log("Connected! to redistogo!");});
rc.on("connect", function() {
rc.subscribe("chat");
console.log("rc connect event");
});
I am successful through here but never get "message."
rc.on("message", function (channel, message) {
console.log("Sending: " + message);
socketio.sockets.emit('message', message);
});
webpage = http.createServer(function(req, res){
console.log('webpage request starting...');
fs.readFile('./index.htm', function(error, content) {
if (error) {
res.writeHead(500);
res.end();
}
else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content, 'utf-8');
}
});
});
webpage.listen(7777);
my client side index.htm is this
<!docttype html>
<html lang="en">
<head>
<script src ="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"> </script>
<script src="http://www.heaphash.com:7777/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('www.heaphash.com', { port: 7777});
socket.on('message', function(data){
var li = new Element('li').insert(data);
$('messages').insert({top: li});
}
</script>
<meta charset="utf-8">
<title>Chat with Redis</title>
</head>
<body>
<ul id="messages">
<!-- chat messages go here -->
</ul>
<form id="chatform" action="">
<input id="chattext" type="text" value="" />
<input type="submit" value="Send" />
</form>
<script>
$('#chatform').submit(function(){
socket.emit('message', $('chattext').val());
$('chattext').val(""); //cleanup the field
return false;
});
</script>
</body>
</html>
how does a client publish to a specific Redis "chat" channel.
If you are using redis pub/sub functionality within your node.js program you should dedicate one redis client connection for listening on some channel and second redis client connection for sending normal commands and/or publishing messages to your channel(s). From node_redis docs:
When a client issues a SUBSCRIBE or PSUBSCRIBE, that connection is put
into "pub/sub" mode. At that point, only commands that modify the
subscription set are valid. When the subscription set is empty, the
connection is put back into regular mode.
If you need to send regular commands to Redis while in pub/sub mode,
just open another connection.
Your problem is also related to these questions:
Redis / Node.js - 2 clients (1 pub/sub) causing issues with writes
Why can't I have a single Redis client acting as PUB and Sub in the same connection?
I believe that the example from that book is missing something, I also read that book and wondered. You are subscribed to the Redis channel and are waiting for messages on the server side, but you never publish to that channel. What is missing is an event listener so when there is a websocket message, you publish that message to the redis channel.