Issue in connecting Rails client to Node server - node.js

I have a chat application on Nodejs+Socket.io which is running on http://localhost:5001 and the other hand there is a rails application which is running on http://localhost:3000
What i want to achieve ?
Connect rails client to node server to talk to each other.
What i did ?
Node server working properly
Added in rails chat page.
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off"/>
<button>Send</button>
</form>
<script src="http://localhost:5001/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:5001');
socket.on('connect', function (data) {
console.log('connected!');
});
</script>
<script>
var socket = io();
$('form').submit(function () {
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function (msg) {
$('#messages').append($('<li>').text(msg));
});
</script>
What is the issue ?
The moment i am loading the page it is showing connected (connected to Node server side also) but just after the first page load port becomes 5001 to 3000 and obviously 404 for socket.io.

Related

Use a different server on a page Angular

I am trying to implement a chat to a view on my Angular / NodeJS website.
The website is deployed on a server running on port 4200, the backend runs on 8000 and for now the chat socket.io template runs on 3000.
I have followed the socket.io's official chat tutorial in detail so I have a functionnal chat page that works on port 3000 but how can I implement it to an Angular component?
Here is my code so far:
server.js:
const app = require('express')();
var http = require('http').Server(app);
var http2 = require('http').Server(app);
var io = require('socket.io')(http2);
http.listen(8000, function(){
console.log('listening on *:8000');
});
http2.listen(3000, function(){
console.log('listening on *:3000');
});
const home = require('./home.js');
const chat = require('./chat.js');
// SOCKET.IO for testing purpose, following the tutorial
app.get('/', function(req, res){
res.sendFile(__dirname + '/socket.html');
});
io.on('connection', function(socket){
...
});
chat.component.html:
<!doctype html>
<html>
<body>
...
<div class="bottom">
<form action="">
<input id="m" class="messageInput" autocomplete="off"/>
<button type="button" class="btn btn-primary btn-lg btn-block">SEND</button>
</form>
</div>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(e){
e.preventDefault(); // prevents page reloading
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
</body>
</html>
I can't figure out to make the chat 'module' work on my HTML page without accessing it through a route (app.get('/', function(req, res){ res.sendFile(__dirname + '/socket.html') });
What can I do? Thanks! And sorry for being a noob :p
Socket.io is different for client side, It's called socket.io-client. You need to get it using:
npm install socket.io-client
Well, Martin you don't need to explicitly link script file in the html. You just need to import socket.io-client variable in its typescript file.
import * as io from 'socket.io-client'. //And then connect using
try {
this._socket = io.connect(socket.io_port_you_are_using_in_server.js)
}
catch (e) {
console.log('error')
}
Now you can use this._socket wherever required like you are doing in server.js.
I also created an app like you using MEAN stack 7 months ago, but I preferred using service as I have to use chat feature in more than 3 components. I'm giving you some sample code which might help you.
joinRoom(room: string, handler: string): Observable<any> {
this._socket.emit('join', { 'room': room, 'handler': handler });
setTimeout(()=>{
console.log(this._socket.id)
},10)
let observable = new Observable((observer) => {
this._socket.on('new user', (data) => {
observer.next(data);
})
})
return observable;
}
leaveRoom(room: string) {
this._socket.emit('leave', room);
this._socket.removeAllListeners()
}
getMessages(): Observable<any> {
let observable = new Observable((observer) => {
this._socket.on('get message', (data) => {
observer.next(data);
})
})
return observable;
}
Just subscribe to the service and use binding to display msgs on the template.
//create array of received msgs
received: any[] = [];
//And in ngOnInit lifecycle hook:
this._chatService.getMessages().subscribe((data) => {
this.received.push(data.msg )
Now you can use *ngFor in the template to display msgs.
<p *ngFor="let msg of received">msg</p>
You can customize code as per your requirement.
Good luck dude!

socket.to(socket.id).emit() does not work

Trying to execute the simplest of targeted messaging in socket.io with no success. According to the documentation for socket.io with express.js you can target a message to a single user socket with socket.to(socket.id).emit('event name', 'message')
I have already read the socket.io docs from start to finish and other stack overflow Q/A here and here and here. Some of the solutions I find involve creating rooms and messaging those rooms, but the objective of this question is to send a message to the socket id using socket.to(socket.id).emit('event name', 'message') as given in the socket.io documention.
I'm using node v6.11.2, express 4.15.2 and socket.io 2.0.3.
The client and server code are taken almost verbatim from https://socket.io/get-started/chat/ with minor changes while I experiment.
index.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
io.on('connection', function(socket){
console.log(req.ip+' connected');
socket.on('chat message', function(msg){
console.log(socket.id);//logs the socket id. Something like 'AUCyM1tnpinCfvfeAAAB'
console.log(msg);//logs whatever the message was, so I know the server is receiving the message
socket.to(socket.id).emit('chat message', 'Nothing is happening here.');
});
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
index.html
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
...
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
</body>
</html>
Change this:
socket.to(socket.id).emit(...)
to this:
socket.emit(...)
Here's an explanation. socket.to(socket.id).emit(...) will broadcast to the room named socket.id. That's OK, there is a room with that name and socket is the only member. But, socket.to() sends to all members of that room EXCEPT socket so there's nobody to send it to.
So, if you want to send just to socket, then just use socket.emit().
Here's a quote from the socket.io doc for socket.to():
Sets a modifier for a subsequent event emission that the event will
only be broadcasted to clients that have joined the given room (the
socket itself being excluded).
Change this :
socket.to(socket.id).emit('chat message', 'Your message');
To this :
io.to(socket.id).emit('chat message', 'Your message');
if you want you can check this link : https://socket.io/docs/emit-cheatsheet/

Socket.io failing to log chat message in console

I'm walking through the Socket.io tutorial on creating a chat room, and I'm having trouble getting my app to log the chat message to the console.
The app is logging when a user connects & disconnects, but it is not logging when a message is passed through.
Any thoughts?
The relevant parts of my index.html page:
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function() {
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
</script>
<body>
<ul id="messages"><ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
My index.js file:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(express.static('public'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('chat message', function(msg) {
console.log("message: " + msg);
});
});
I've gotten it to work!
Steps to solution:
- separate the script tag with the event listener into a separate JS file
- include that JS file in the same place the script tag was originally
- load the chatListener when the document is ready
My files now look like this and everything works beautifully:
index.html:
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script src="main.js"></script>
<body>
<ul id="messages"><ul>
<form action="">
<input class="chat" id="m" autocomplete="off" />
<input class="btn" type="submit" value="Send" />
</form>
</body>
index.js: nothing changed
main.js:
var socket = io();
var chatListener = function() {
$('form').submit(function() {
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
}
$(document).ready(function() {
chatListener();
})
In the end, I think it was a beginner's JS mistake; I was loading the script at the top of the page (as the tutorial suggested), and the event listener on the form was never registering.

Redis Cookbook Chat Recipe

I am a new starter to Node.Js and Redis. I got the Redis cookbook and was trying out the Chat client & Server recipe.
I was wondering if anybody got the code to work or if there is some bug in the code.
I dont see where the sent messages from the client get invoked on the server.
Any help would be great.
Regards,
Tom
Client Code:
<?php
?>
<html>
<head>
<title></title>
<script src="http://192.168.0.118:8000/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script>
var socket = io.connect('192.168.0.118',{port:8000});
socket.on('message', function(data){
alert(data);
//var li = new Element('li').insert(data);
//$('messages').insert({top: li});
});
</script>
</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', 'test'); //$('chattext').val());
$('chattext').val(""); // cleanup the field
return false;
});
</script>
</body>
</html>
Server Code:
var http = require('http');
io = require('socket.io');
redis = require('redis');
rc = redis.createClient();
//rc1 = redis.createClient();
rc.on("connect",function(){
rc.subscribe("chat");
console.log("In Chat Stream");
});
rc.on("message",function (channel,message){
console.log("Sending hope: " + message);
//rc1.publish("chat","hope");
socketio.sockets.emit('message',message);
});
server = http.createServer(function(req,res){
res.writeHead(200,{'content-type':'text/html'});
res.end('<h1>hello world</h1>');
});
server.listen(8000);
var socketio = io.listen(server);
It looks like you're not listening for any connect / message events from socket.io.. try something like
socketio.sockets.on('connection', function(socket) {
console.log("Got connection");
socket.on('message', function(msg) {
rc1.publish("chat", msg);
});
});
You'll need to uncomment your rc1 up there, you will need that second redis connection

node.js socket.io simple chat

I'm starting playing with node.js and as everybody, I want do a chat.
My idea is run node.js with socket.io in the port 9090, for example, and my client html in the port 8080. My html client will be served independent.
My server:
var sys = require('sys');
var express = require('express');
var io = require('socket.io');
var app = express.createServer();
app.listen(8080);
var socket = io.listen(app);
socket.on('connection', function (client) {
client.on('message', function (msg) {
socket.broadcast(msg);
});
client.on('disconnect', function () {
});
});
My client:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="http://cdn.socket.io/stable/socket.io.js"></script>
<script>
$(document).ready(function () {
var socket = new io.Socket("localhost", {port: 8080});
socket.on('connect', function () {
socket.send('A client connected.');
});
socket.on('message', function (message) {
$('div#messages').append($('<p>'), message);
});
socket.on('disconnect', function () {
console.log('disconnected');
});
socket.connect();
$('input').keydown(function (event) {
if(event.keyCode === 13) {
socket.send($('input').val());
$('input').val('');
}
});
});
</script>
</head>
<body>
<input type="text" style="width: 300px;" />
<div id="messages" style="border:solid 1px #000;"> </div>
</body>
</html>
I'm running in ubuntu 11.04 with node.js v0.4.10.
The server works fine, but the client can't do connection, in the console.log on google Chrome I received this message:
XMLHttpRequest cannot load http://localhost:8080/socket.io/xhr-polling//1311465961485. Origin http://localhost is not allowed by Access-Control-Allow-Origin.
The server.js is in a folder in /var/www/cliente/chat/public.
What's the problem?
Your client code is not actually being served from port 8080 as you want.
var sys = require('sys');
var express = require('express');
var io = require('socket.io');
var app = express.createServer();
app.listen(8080);
app.use(express.static(__dirname));
app.get('/', function(req, res){
res.render('index.html', { title: 'Chat' });
});
var socket = io.listen(app);
socket.on('connection', function (client) {
client.on('message', function (msg) {
socket.broadcast(msg);
});
client.on('disconnect', function () {
});
});
This should fix your Access-Control-Allow-Origin errors. Execute node server.js and connect to http://localhost:8080. A couple additional notes:
Make sure you have installed socket.io 0.6.x since that's what you are including in your html file. 0.7.x is backwards incompatible.
With this configuration you'll be running socket.io on the same port you are serving your page from (as opposed to 9090).
When I updated my client to:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script src="http://localhost:8080/socket.io/socket.io.js"></script>
<script>
var socket = io.connect("http://localhost", {port: 8080});
socket.on('connect', function () {
socket.send('A client connected.');
});
socket.on('message', function (msg) {
$('div#messages').append($('<p>'), msg);
});
socket.on('disconnect', function () {
console.log('disconnected');
});
$(document).ready(function(){
$('#btn_send').click(function (event) {
socket.send($('#txt_msg').val());
$('#txt_msg').val('');
});
});
</script>
</head>
<body>
<input type="text" id="txt_msg" style="width: 300px;" /><input type="button" id="btn_send" value="send" />
<div id="messages" style="border:solid 1px #000;"> </div>
</body>
</html>
Everything worked.
I was using a version 0.7 of the socket.io that was the problem: https://github.com/LearnBoost/Socket.IO/wiki/Migrating-0.6-to-0.7
You cannot make AJAX requests to URLs that are not on the same hostname and port as the current page. It's a security restriction in all web browsers.

Resources