I'm trying to develop a Faye server side client to run automatically as needed. In the official website of Faye, I find only document about server side client, there is no information about how to run it.
Please tell me how to do so
Thanks
There's a key missing piece in the documentation. It appears you need to call client.connect() in order to receive events.
Here is what worked for me:
var faye = require('faye');
var client = new faye.Client('http://localhost:8000/faye');
//This was missing from the documentation
client.connect();
var subscription = client.subscribe('/foo', function(message){
console.log("Event Received");
console.log(message);
})
//This is optional
subscription.then(function() {
console.log('Subscription is now active!');
});
var publication = client.publish('/foo', {text: "Hello World!"});
publication.then(function() {
console.log('Message received by server!');
}, function(error) {
console.log('There was a problem: ' + error.message);
});
just stumpled on this through Google. You should be able to run a client using just this code:
var faye = require('faye'),
client = new faye.Client('http://example.com/faye');
client.subscribe('/some/channel', function(message) {
// process message
});
If you still have trouble, please get on the mailing list at http://groups.google.com/group/faye-users
Create a .rb file and fill with following code
require 'rubygems'
require 'faye'
cliv=Faye::RackAdapter.new(
:mount => '/cliv',
:timeout => 25
)
cliv.listen(3000)
Go to console and type
ruby your_file.rb
Once you have done. create a js with html as following :
<script type="text/javascript" src="http://localhost:3000/faye.js"></script>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js'></script>
<script>
$("document").ready(function(){
faye = new Faye.Client('http://localhost:3000/faye');
faye.connect();
subscribeObj = faye.subscribe("/hi", function(message) {
$("#response").append(message.text);
$("#content").val("");
});
$("#say").click(function(){
content=$("#content").val();
faye.publish("/hi", {text: content});
});
});
</script>
<div id='response'></div>
<br/>
<input type='text' id='content' />
<div style='cursor:pointer;' id='say'> Say Something </div>
And I think u r ready to go. :)
Related
I am new in socket.io. I wanted to develop an small application using it. I know the basic of socket.io. I have followed this and this documentation.
I am also able to make this simple connection. Code :
Client:
<script src="/socket.io/socket.io.js"></script>
<script>
console.log(location.protocol+'//'+location.host);
var socket = io.connect(location.protocol+'//'+location.host), socketwithApi = io.connect(location.protocol+'//'+location.host + '/apikey/');
</script>
<script type="text/javascript">
var i=0;
$(document).on('click','#socket-emit-btn', function(){
let message = location.href;
socket.emit("test",message);
});
socket.on("testlistened",function(data){
i ++;
console.log(i);
console.log(data);
if(data){
$("#console-div").html(data);
}else{
$("#console-div").html("{empty}");
}
});
socketwithApi.on('apikey',function(data){
console.log(data);
});
</script>
Server:
//consider everything needed is defined
var apikey = io
.of('/apikey/')
.on('connection', function (socket) {
socket.emit('apikey', { news: 'item' });
});
io.on('connection', function (socket) {
let clientID = socket.id
let clientIP = socket.handshake.address
if (client) client.socket = socket
console.log('User-Client Connected!: IP: ' + clientIP)
socket.on("test",function(data){
console.log("listened");
let ParsedData = url.parse(data);
let responseData = {
UrlScheme:ParsedData,
socketID: clientID,
api_key: ParsedData.pathname
}
console.log(responseData);
console.log(`${TRANSACTIONGETRECEIPT}_RESPONSE`)
socket
.binary(true)
.emit('testlistened', JSON.stringify(responseData))
});
socket.on('disconnect', function (data) {
console.log(clientID + ' has disconnected')
})
})
Everything is working fine, i am able to emit and listen both from the server side and client side. But I did not find the documentation which would tell if it is possible to send http get or post request from the browser or postman to socket.io . Is it only possible to send request from a page where socket client is present or can we also send request like
http://localhost:8099/api-hastgraph-key/socket.io/?EIO=3&transport=websocket&sid=w0kDs4oGI7SVwB3YAAAC
or http://localhost:8099/socket.io/api-hastgraph-key?EIO=3&transport=websocket&sid=w0kDs4oGI7SVwB3YAAAC
from browser and connect to socket.
Thank you. Any kind of help are highly appreciated.
I am using the node.js agent for the new relic. I am using Node.js custom instrumentation to monitor socket.io, new relic web transaction appearing under root and no data is visible as I am not able to monitor socket.io. Below is the output under Transaction Root Path
Breakdown table
Category Segment % Time Avg calls (per txn) Avg time (ms)
WebTransaction Root path 100.0 1.0 2,150
Server Code
var http = require('http'),
fs = require('fs'),
nr = require('newrelic'),
index = fs.readFileSync(__dirname + '/sock_client.html');
var app = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
});
// Socket.io server listens to our app
var io = require('socket.io').listen(app);
// Send current time to all connected clients
function sendTime() {
io.emit('time', { time: new Date().toJSON() });
}
// Send current time every 10 secs
setInterval(sendTime, 10000);
// Emit welcome message on connection
io.on('connection', function(socket) {
// Use socket to communicate with this particular client only, sending it it's own id
socket.emit('welcome', { message: 'Welcome!', id: socket.id });
socket.on('rings', function(data){
nr.startWebTransaction('websocket/ping/test_v3', function transactionHandler() {
socket.emit('pong', { message: 'Welcome!' });
console.log(data);
nr.addCustomParameters({
"Discount Code": "Summer Super Sale",
"Item Code": 31456
});
});
});
socket.on('pings', function(data){
nr.startWebTransaction('websocket/ping/test_v5', function transactionHandler() {
let trans = nr.getTransaction();
someAsyncBeha("console.log", function(){
trans.end();
})
console.log(data);
});
});
});
function someAsyncBeha(data, cb){
setTimeout(function() {
console.log("Goodbye!");
console.log(data);
cb();
}, 5000);
};
Client Code
<!doctype html>
<html>
<head>
<link rel="shortcut icon" href="/favicon.png">
<script src='/socket.io/socket.io.js'></script>
<script>
var socket = io();
socket.on('welcome', function(data) {
addMessage(data.message);
// Respond with a message including this clients' id sent from the server
socket.emit('rings', {data: 'foo!', id: data.id});
});
socket.on('time', function(data) {
addMessage(data.time);
socket.emit('pings', {data: 'foo!', id: data.time});
});
socket.on('error', console.error.bind(console));
socket.on('message', console.log.bind(console));
socket.on('pong', console.log.bind(console));
function addMessage(message) {
var text = document.createTextNode(message),
el = document.createElement('li'),
messages = document.getElementById('messages');
el.appendChild(text);
messages.appendChild(el);
}
</script>
</head>
<body>
<ul id='messages'></ul>
</body>
</html>
The issue was in the new relic module version, there are two suggestions.
First, upgrade the Node.js agent to v2.2.0
This version includes a bug fix that should resolve the issue you're seeing.
Second, move nr = require('newrelic'); to the top of the requires.
This ensures the agent catches everything in your application before the code has a chance to spin up. Without this, the code in the other requires can launch before the agent has a chance to inject its methods, resulting in no tracking for those methods.
I've been fiddling around with socket.io and express. And I,m using Mongoose in this project. I have this code:
Server
io.on('connection', function (socket) {
setInterval(function(){
Data.find({}, {name:1, _id:0}, {sort : { _id : -1 }}, function (err, data) {
if (err) {
console.log(err);
} else {
socket.emit('data', {datas: data});
};
})
}, 500);
});
Client
var socket = io.connect();
socket.on('data', function (data) {
if (data) {
$('#names').html('');
$.each(data.datas, function (index, value) {
$('#names').append('<li>'+ value.name +'</li>')
})
};
});
Is it proper to execute setInterval on socket.io connection to load the necessary data from the database to send it continuously to the client? Will this affect the server in performance? If it does, whats the best way to fetch data from mongodb to the client side continuously? Is there a way to watch (or something like database trigger) the collections in mongodb if someone from the user/client side adds data? In my code, Am I doing the right thing in placing the mongodb query inside the setInterval function? I'm new in using node.js, socket.io and mongodb. Can someone direct me to the right path? Thanks in advance!
Here is what I have accomplished rather than using the setInterval method in case someone wants to know how i did it on my project. Thanks to #Mariusz comment
"how about a simple HTTP webservice called by the one who writes to
the database?"
gave me an idea. Instead, what I did is add an event click method on the form submit with socket.emit('client_data', {'data': $(this).serializeArray()}); to send the data to the server. Then on the server I call socket.on('client_data') method to fetch the data from the client to save it to the database and called io.sockets.emit method from the callback to send back the updated data to the client (reference on how to send responses to clients). Sorry if can't explain it even better, but here's the code so you could figure it out.
Client
<script src="/js/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<form id="form" method="post">
<label for="name">Name: <input id="text"type="text" name="name"></label>
<button id="submit" name="submit">save</button>
</form>
<ul id="names">
{% if datas %}
{% for data in datas %}
<li>{{data.name}}</li>
{% endfor %}
{% else %}
<li>No data</li>
{% endif %}
</ul>
<script>
$(document).ready(function(){
var socket = io.connect();
socket.on('data', function (data) {
if (data) {
$('#names').html('');
$.each(data.datas, function (index, value) {
$('#names').append('<li>'+ value.name +'</li>')
})
};
});
$('#form').on('submit', function(e){
e.preventDefault();
socket.emit('client_data', {'data': $(this).serializeArray()});
$('#text').val('').focus();
})
});
</script>
Server
io.on('connection', function (socket) {
socket.on('client_data', function(data){
Data.create({
name: data.data[0].value
}, function (err, newData) {
console.log(newData.name + ' is now saved in the database.')
Data.find({}, {name:1, _id:0}, {sort : { _id : -1 }}, function (err, data) {
if (err) {
console.log(err);
} else {
io.sockets.emit('data', {datas: data});
};
})
})
});
});
Now everytime a user/client updates the data, all the page will be updated as well without using setInterval to refresh the data.
Hope it helps!
Maybe you're better off with a messaging queue solution like RabbitMQ? This way you can send messages from one process to another and it is automatically notified. I've implemented notifications in an application using Node.js, socket.io and RabbitMQ (if it's near the area of your interest). It's an open-source project that I'll share if you want to (it's on GitHub but changes are not yet merged).
In any case, in situations like this, events are always better than polling (if only possible).
I tried to ask this on the socket.io google group but no one could (or didn't wanted to) help me.
I have this piece of code on the server side:
var chat = io
.of('/chat')
.on('connection', function (socket) {
socket.emit('message', {
that: 'only'
, '/chat': 'will get'
});
});
chat.on("message", function(data){
console.log(data);
});
While on the client side I have this code:
var chat = io.connect('http://localhost/chat');
chat.on('message', function (data) {
chat.emit('hi!');
});
chat.emit("message", {"this": "is a message"});
On the console I can see that the first message from the server is sent but it seems like the client, once connected and received the message, doesn't emit the 'hi!' message. Moreover I want the client to emit also another message, namely the last line I pasted. Also this message is not received by the server (which in theory should log it).
I'm surely doing something wrong, can anyone point out where exactly this is happening?
What I want to achieve in the end is just setting up a simple chat-like system, but I want this stuff (the channels) working before actually writing the chat itself. Thanks
The reason why that it doesn't the "hi" is not sent is because the first argument in .emit is the event name, in which in here, it is "hi". Technically if you do the following on the server side, I think you should get an undefined data(since you didn't put anything as the second argument which is the object to be sent):
.on('hi',function(data){
console.log(data) // should log "undefined"
});
You can also use .send which is like the web-sockets semantics, and sends to the the message event. If you change the .emit to .send in the client side, it should work.
In summary:
.emit('eventName', 'data') // sends to the eventName name
.send('data') // sends to message event
Working client side code:
var chat = io.connect('http://localhost/chat');
chat.on('message', function (data) {
chat.send('hi!');
});
chat.emit("message", {"this": "is a message"});
I dumbed it down a little bit, but:
Server:
var io = require('socket.io').listen(8080);
var chat = io
.of('/chat')
.on('connection', function (socket) {
socket.send('welcome to the interwebs');
socket.on('message', function(data) {
console.log(data);
});
});
Client:
<html>
<body>
<script src="http://10.120.28.201:8080/socket.io/socket.io.js"></script>
<script type="text/javascript">
var chat = io.connect('http://10.120.28.201:8080/chat');
chat.on('connect', function () {
console.log("connected");
chat.send('hi!');
chat.on('message', function (data) {
console.log(data);
});
});
</script>
</body>
</html>
I am messing around with socket.io and node.js, and was wondering how to accomplish the following: I have a simple form that sends a text string to the server, and the server sends it back, and it gets appended to a div. what I would like to do is have that div update for all users in all browsers, currently it only updates the one that the message was sent from.
code from app.js (node.js server) :
io.sockets.on('connection', function(socket) {
socket.on('send_message', function(data) {
data.message = data.message + ' yo<br/>';
socket.emit('get_message',data);
});
});
code on client-side:
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js" type="text/javascript"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
$(document).ready(function() {
var socket = io.connect('http://localhost:3000');
$('#sender').live('click',function() {
var user_message = $('#message_box').val()
socket.emit('send_message',{message: user_message});
});
socket.on('get_message', function(data) {
$('#data').append(data.message);
});
});
</script>
and the html:
<div id='data'></div>
<input type='text' id='message_box' placeholder='send message'>
<button id='sender'>Send Message</button>
what should I be doing to send messages to multiple browsers?
Change
socket.emit('get_message',data);
To
socket.broadcast.emit('get_message',data);
To broadcast it to all connected users, except to the socket where you are calling the broadcast on.
If you also want to include that socket you can do
io.sockets.emit('get_message', data);