I'm building a node app where users can select keywords to follow on Twitter. Their 'wall' will be automatically updated as new tweets come in with their selected keywords.
The way I've built it is each user joins their own room named with their user id. The tweets should then be pushed to their room and prepended to the list with jQuery.
The problem is If I open 4 tabs and log 4 different users in it only updates the first 2 that were logged in with their Twitter feed! It doesn't matter which order I log them in it's only the first to that receive updates.
When logging the error I get: Exceeded connection limit for the user
I'm guessing Twitter only allows a single connection per API account. Is this correct?
Is there any way around this as I need individual streams for each user?
My server code is:
var socket = require( './public/node_modules/socket.io' );
var express = require('./public/node_modules/express');
var request = require('./public/node_modules/request');
var Twitter = require('./public/node_modules/twitter');
var app = express();
var server = require('http').createServer(app);
var io = socket.listen( server );
var port = process.env.PORT || 4321;
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
//setup Twitter Details
var watchList = ['ferrari'];
var T = new Twitter({
consumer_key: 'xxx'
, consumer_secret: 'xxx'
, access_token_key: 'xxx'
, access_token_secret: 'xxx'
});
io.on('connection', function (client) {
client.on('join', function(data)
{
//send to the user in question i.e client
client.emit('update','You are connected');
//send to ALL users
io.sockets.emit('update', 'New user '+data.name+' has joined');
client.join(data.id, function()
{
console.log('JOINING ROOM: '+data.id+' following: '+data.following);
if(data.following!='')
{
T.stream('statuses/filter', {track: data.following}, function(stream) {
stream.on('data', function(tweet) {
client.emit('stream',tweet.text);
//io.sockets.to(data.id).emit('stream', tweet.text);
});
stream.on('error', function(error) {
console.log(error);
});
});
}
});
});
});
Thanks in advance
Related
I'm actually trying to make a real-time connection between two different apps. I've found a bunch of tutorials about how to make a chat using socket.io, but that doesn't really help me since it's just the same app duplicated in multiple windows.
I'm making a pick & ban overlay for League of Legends in local development. My first thought was to display the empty overlay on one hand and create an interface to manually update it on the other hand. Socket.io seems to be the right thing to use in my case since it can provide new data without having to reload the component.
This is what I wrote in both apps :
const express = require('express');
const socket = require('socket.io');
// App setup
const app = express();
const server = app.listen(4200, function () {
console.log('Listening to requests on port 4200')
});
// Static files
app.use(express.static('public'));
// Socket setup
const io = socket(server);
io.on('connection', function (socket) {
console.log('Made socket connection', socket.id);
socket.on('change', function (data) {
io.sockets.emit('change', data);
});
});
But I fail to connect them as they have to listen to the same port. What am I doing wrong?
(Forgive my bad English and lack of syntax, I'm doing my best here. :p)
I am certainly not an expert on network programming, but as far as I know you need to have one listening app (backend) and another one to connect to it (client). And you define what happens with all the data (messages) that backend recieves (for example sending the messages it recieves to all the clients in the same chat room).
If I am correct to assume you are trying to connect two listening apps?
simple google search of "nodejs socket server client example" revealed this https://www.dev2qa.com/node-js-tcp-socket-client-server-example/ might wanna take your research in this direction
u can try something like this way
var express = require('express');
var socket = require('socket.io');
// App setup
var app = express();
var server = app.listen(8080, () => {
console.log('App started')
})
// Static file
app.use(express.static('public'))
// Socket SetUp
var io = socket(server);
io.on('connection', socket => {
console.log('made the connection')
socket.on('chat',data => {
io.sockets.emit('chat',data)
});
socket.on('typing',data => {
socket.broadcast.emit('typing',data);
});
})
create another file and
var socket = io.connect('http://localhost:8080')
// Elenment
var message = document.getElementById('message');
handle = document.getElementById('handle');
btn = document.getElementById('send');
output = document.getElementById('output');
feedback = document.getElementById('feedback');
// Emit Events
btn.addEventListener('click', () => {
socket.emit('chat', {
message: message.value,
handle: handle.value
})
})
message.addEventListener('keypress', () => {
socket.emit('typing', handle.value)
})
socket.on('chat',data => {
feedback.innerHTML = '';
output.innerHTML += '<p><strong>' + data.handle +': </strong>' +
data.message + '</p>'
})
socket.on('typing', data => {
feedback.innerHTML = '<p><emp>' + data + ' is typing a message... </emp></p>'
})
details are given here node socket chat app
Ok, figured it out. Here's how it works using express and vue together :
First, setup socket.io in your express server js file :
const express = require('express')
const { Server } = require('socket.io')
const http = require('http')
const app = express()
const server = http.createServer(app)
const io = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST', 'REMOVE']
}
})
const PORT = process.env.PORT || 8080
io.on('connection', (socket) => {
console.log('New socket user')
socket.on('SEND_MESSAGE', data => {
console.log('received message in back')
io.emit('MESSAGE', data)
})
})
server.listen(PORT, () => { console.log(`Server started on port : ${PORT}`)})
As you can see we received from the client "SEND_MESSAGE" and we trigger MESSAGE from the server to forward the information to all the clients. The point I was missing is that we bind SEND_MESSAGE on the socked created from the connection but we emit from the io server.
Now you vue part :
import io from 'socket.io-client'
export default {
data() {
return {
messages: [],
inputMessage: null,
socket: io('http://localhost:8080')
}
},
mounted() {
this.socket.on('MESSAGE', data => {
this.messages.push(data)
})
},
methods: {
sendMessage() {
const message = {
senderID: this.myID,
message: this.inputMessage,
sendAt: new Date()
}
this.socket.emit('SEND_MESSAGE', message)
this.inputMessage = null
},
},
}
I'm using node and express to access the twitter api. the following code gives me a 401 error. I've tried changing my apps access to read, write and access, and regenerating my api keys, but that still gives me an error saying that it can't authenticate me. I read on the twitter forums that leaving the url callback field in the api app settings might be causing this, but that didn't fix it either.
const port = (process.env.VCAP_APP_PORT || 3000);
const express = require("express");
const twitter = require('twitter');
const app = express();
const twitterClient = new twitter({
consumer_key: 'key',
consumer_secret: 'key',
access_token_key: 'key-key',
access_token_secret: 'key'
});
app.get('/hello', (req, res) => {
twitterClient.stream('statuses/filter', {track: 'javascript'}, function(stream) {
stream.on('data', function(event) {
console.log(event && event.text);
});
stream.on('error', function(error) {
throw error;
});
});
});
I have a use case where I need to take input from browser pass it to my node server over a socket, this input is then send to a third party website for processing again over socket. The result received from the third party website needs to be sent back to browser.
node server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var socketIO = require('socket.io'),
server, io;
var thirdPartSocketClient = require('socket.io-client');
//Custom imports
var thirdParty = require('./ms_socket.js');
var socket = socketIO(server);
socket.on('connection', function(client) {
var token = null;
//Token from third party site that we should have before sending the actual info
thirdParty.getToken(function callback(returnToken) {
token = returnToken;
});
thirdPartSocketClient = thirdParty.getTranslation(token);
client.on('audio', function(data) {
thirdPartSocketClient.emit(data);
});
});
server.listen(8080, function() {
console.log('Open http://localhost:8080 in your browser');
});
ms_socket.js
//Exported function making a socket call to third party service
var exports = module.exports = {};
var request = require('request');
var wsClient = require('socket.io-client');
var fs = require('fs');
exports.getToken = function(callback) {
//send back the token
}
exports.getTranslation = function(accessToken) {
var ws = new wsClient(thirdPartySocketURL);
// event for connection failure
ws.on('connectFailed', function(error) {
console.log('Initial connection failed: ' + error.toString());
});
// event for connection succeed
ws.on('connect', function(connection) {
console.log('Websocket client connected');
// process message that is returned
//processMessage would process the incoming msg from third party service
connection.on('message', processMessage);
connection.on('close', function(reasonCode, description) {
console.log('Connection closed: ' + reasonCode);
});
// print out the error
connection.on('error', function(error) {
console.log('Connection error: ' + error.toString());
});
});
// connect to the service
ws.connect(thirdPartySocketURL, null, null, {
'Authorization': 'Bearer ' + accessToken
});
return ws;
}; //End of export function
I am able to receive the data from browser, make a connection to third party service (can see the socket connection) and emit the data. however I am unable to receive the reply back from the third part service.
Is it because node is not listening to my socket events of thirdparty ?
Not sure exactly why its not working.
I save the data locally on the server, read the file and then send it, then I get a response back from the service.
If this is not a "right" design can you please suggest a good way, should I be using message queues (if yes, feel free to recommend one)
Thanks
I am using a TCP connection via node.js to connect to a certain port in windows, however I want the connection to be established until the user logs out .
In other words I want to add the TCP Connection as a session attribute in node.js ,so that it will last as long as the session is alive for the user.
I have tried this ,but it doesn't work.
Code :
var express = require('express');
var authRouter = express.Router();
var createTCPConnection = function () {
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
client.write('I am Chuck1 Norris!');
});
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
// Close the client socket completely
//client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
return client;
};
authRouter.route('/').get(function(req, res) {
var sess = req.session;
if (sess.username) {
//If Session has username attribute, it is a valid session
res.render('dashboard', {
title : 'Welcome To Operator Screen',
username : sess.username
});
if(sess.tcpClient === undefined) {
console.log('Establishing TcpClient');
sess.tcpClient = createTCPConnection();
} else {
console.log('TcpClient already established');
}
} else {
//Invalid/expired session, redirect to homepage
res.redirect('/logout');
}
});
module.exports = authRouter;
I'm new to socket.io, and I'm doing a simple API with NodeJS (express 4). I'm developing an action that is similar to the old "poke" action at facebook. A user send a poke to other user, and this one gets a notification on real time (this is the reason why I am using socket.io).
This is the code:
app.js
var port = 3000;
var app = module.exports = express();
var server = require('http').Server(app);
...
server.listen(port);
require('./config/socket-io')(app, server, secret);
socket-io.js
module.exports = function(app, server, secret) {
var clients = {};
console.log("initiating sockets...");
var sio = require('socket.io').listen(server, {'log level': 2});
sio.on('connection', function (socket) {
console.log("...new connection: "+socket.client.id);
clients[socket.id] = socket;
socket.emit('identification', { data : socket.client.id });
socket.on('newShoutOut', function(data) {
var receptor = data.idTo;
var emiter = socket.client.id;
console.log("...new shout out from " +emiter+ " to "+receptor);
sio.sockets.sockets[receptor].emit({ data : data.data, from : emiter });
});
socket.on('disconnect', function() {
console.log("..."+socket.client.id + " disconnected");
});
});
};
Here you can differentiate three states:
Connection: The server detects all the clients connection to the host:port. After that, the server sends to each client his ID. This works fine.
Send message: One client sends a notification to other client. For now, the server receives the notification from one client, but the "receiver" doesn't receive anything.
Disconnection: Doesn't matter in this case.
My question is, what is the way to send a message to a client directly knowing the ID? What I am doing wrong? I tried so many options to send a message directly to a specific client ID but didn't work...
EDIT
Frontend
var socket = io('http://localhost:3000');
var id = "";
socket.on('connection', function (data) {
console.log("connected!");
console.log(data);
});
socket.on('identification', function(data) {
id = data.data;
$("#socket_info h1").html("ID: "+id);
});
socket.on('newShoutOut', function(data) {
console.log("newShoutOut received!");
});
Ok, so I assume the shoutout is coming from a user? You will need to create the event on the clientside, such as:
var button = $('#button');
button.on('click', function() {
var msg = 'message',
userID = '123'; //get the ID who they are messaging
socket.emit('sendShoutOut', {msg: msg, id: userID});
});
Then you will need to receive that response on the server, and reply to the user in that function:
socket.on('sendShoutOut', function( data ) {
socket.sockets.sockets[data.id].emit('sendPrivateMsg', { data : data.msg, from : emiter });
});
Lastly, the reciever must be notified, so you will need to handle the response on the client:
socket.on('sendPrivateMsg', function( data ) {
alert(data);
});
Hope this helps.