Possible scoping issue - node.js

A possible node.js/backbone.js/socket.io scoping issue I can't wrap my head around.
(snippet from) server.js
var app = express();
var server = http.createServer(app);
io = io.listen(server);
(snippet from) index.html
<script type="text/javascript" src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect(window.location.origin);
</script>
(snippet from) js/views/map.js
(function() { // self invoking anonymous function so we are able to
// create the private variable "map" that can be shared here
var map;
var webSocket = window.socket;
window.MapView = Backbone.View.extend({
initialize: function() {
this.render();
webSocket.on("marker dropped", this.propNewMarker);
},
events: {
"click .dropmarker" : "dropMarker"
},
dropMarker: function(event) {
console.log("This fires!!!");
webSocket.emit('marker dropped', { my: 'data' });
},
propNewMarker: function() {
console.log("someone dropped a marker (im in map.js)");
},
(snippet from) MapView.html
Drop marker
Behavior I am going for
Clicking on the "dropmarker" button in MapView.html should instigate the webSocket.emit action in dropMarker. (it fires off the console.log without any problems)
Tested
When I add
io.sockets.emit('marker dropped', { 'message': 'ello wurldz' });
into server.js, the propNewMarker function in map.js is fired correctly.
Preliminary conclusion
It seems that I am struggling with a scoping issue at the level of the buttonclick.
I'm not able to fire a websocket event there.
Any thoughts ? or should I offer more insights in the code before this can be debugged? (tried to keep it as clean as possible)

This doesn't look like an issue with the scope but in fact how you are using the socket
In order for propNewMarker to be called the server must emit a message on marker dropped
On the server if you add
io.sockets.on('connection', function (socket) {
socket.on('marker dropped',function(msg){
socket.emit('marker dropped',msg);
});
});
Then the client should respond just fine to the event. I did some testing and it looks like your scoping is just fine.

Related

Enter twice in socket.on event

I'm new to Angular and Node.js.
My code executes a socket.emit to a server side function and receives a response in the socket.on event ('listartists').
Unfortunately, he enters twice in this event and I do not understand why.
On the server side (app.js) I put logs and the function is called correctly once, but then it goes through the socket.on twice ('listartists').
Thank you all
var appAng = angular.module('appAng', []).controller('myCtrl', function($scope) {
socket.on('listartists', function(msg) {
// !!! enter twice this part of the code
var ClientMessage = JSON.parse(msg);
if (ClientMessage.ClientID == GetClientUniqueId()) {
var artistslist = JSON.parse(ClientMessage.Message);
$scope.$apply(function() {
var artistslist=JSON.parse(ClientMessage.Message);
$scope.artists = artistslist;
});
}
});
});
i modified my code as :
socket.on('listartists', function(msg){
var ClientMessage=JSON.parse(msg);
if (ClientMessage.ClientID== GetClientUniqueId())
{
console.log("Arriva Lista Artisti " + ClientMessage.ClientID);
var artistslist =JSON.parse(ClientMessage.Message);
$scope.artists = artistslist;
$scope.$apply( function(){});
}
});
Anyway if i remove $scope.$apply( function(){}); the socket.on event is called only once,
otherwise it passes twice from there.
I think the problem is the management of the SCOPE some idea?

Testing Node.js server and Flash socket

I'm trying to establish socket connexion between a Node.js server and a Flash (Flex) application. I have some unexpected results that I can't explain by myself.
Here are my code.
Flex :
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="windowedapplication1_creationCompleteHandler(event)">
<fx:Script>
<![CDATA[
import com.pnwrain.flashsocket.FlashSocket;
import com.worlize.websocket.WebSocket;
import mx.events.FlexEvent;
private var _flashSocket:FlashSocket;
private var _webSocket:WebSocket;
private var _xmlSocket:XMLSocket;
protected function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
{
_xmlSocket = new XMLSocket();
_xmlSocket.addEventListener(Event.CLOSE, function():void{trace('close')});
_xmlSocket.addEventListener(DataEvent.DATA, onData);
_xmlSocket.addEventListener(Event.CONNECT, function():void{trace('connect');});
_xmlSocket.addEventListener(IOErrorEvent.IO_ERROR, function():void{trace('io error')});
_xmlSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, function():void{trace('sec error')});
_xmlSocket.connect("127.0.0.1", 8888);
}
protected function button1_clickHandler(event:MouseEvent):void
{
_xmlSocket.send("client test");
}
protected function onData(event:DataEvent):void
{
trace(event.data);
}
]]>
</fx:Script>
<s:VGroup>
<s:TextInput id="ti" />
<s:Button label="test" click="button1_clickHandler(event)" />
</s:VGroup>
</s:WindowedApplication>
My simple Node.js server :
const net = require('net');
var server = net.createServer(function(socket)
{
socket.on("data", function(message){
socket.write(message + "\n");
});
socket.on("connect", function(){ // Never triggered
console.log("connected to client\n");
});
socket.on("drain", function(){ // Never triggered
console.log("drain !\n");
});
socket.on("close", function(){
socket = undefined;
});
setInterval(function(){
if(socket)
{
socket.write("test\n");
}
}, 5000);
}).listen(8888, "127.0.0.1");
So when I click on my Flex button, data is sending from my app to my server and from my server to my app so it seems to be good.
When I waiting for 5 seconds my Flex does not receive "test" String as expected but when I click on my app button after 1 minute or less I receive data like this :
test
test
test
test
.....
client test
It seems that my server doing some "retention of information" but I can explain why or why some events are never triggered as it should be (?).
Thanks for help
Ok I'm just finding solution after posting (it's always the case no ?)
I have to use \0 in message.
socket.write("test\0");
NOT
socket.write("test\n");

socket.io emit in loop until client responds?

I would like to emit a message to the client every X seconds until the client clicks a button and acknowledges receipt.
Any ideas on how I might accomplish this? New to Node but I am hoping I can get this done with Node and Sockets.io.
Thanks in advance for any insight or help to get me in the right direction.
I think the best way to accomplish this would be to create a new class that extends the "vanilla" Node.js event class. You will need to require it first like so:
const EventEmitter = require('events');
class MyEmitter extends EventEmitter {}
https://nodejs.org/api/events.html
Once you've got your class, what you will need to do is creating a child process, to do so, you can refer to the official documentation here:
https://nodejs.org/api/child_process.html
Inside this process you can create your loop and send a message through the socket. The goal of extending the events class is to be able to create an Inside event emission which you can listen to detect specific events (like socket closed, or anything you'd like to track)
I hope this answers your question.
This is a simple setup just to give you an idea of how to do it:
node server (very basic, only socket.io, nothing else):
const io = require('socket.io')(3000);
const interval = 1000;
io.on('connection', function (socket) {
console.log(socket.id + ' has connected');
var foo = setInterval (function () {
socket.emit('foo');
}, interval);
socket.on('confirmed', function () {
console.log('confirmation received from ' + socket.id);
clearInterval(foo);
});
});
console.log('socket.io server started at port 3000');
index.html (open it in your browser and see what happens):
<!doctype html>
<html>
<head>
<title>Testing socket.io</title>
</head>
<body>
<button id="button">Confirm</button>
<p id="socket">waiting...</p>
<p id="alert">foos counter: </p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.min.js"></script>
<script>
var socket = io("http://localhost:3000");
var counter;
socket.on('connect', function() {
counter = 0;
document.getElementById("socket").innerHTML = "connected";
document.getElementById("button").addEventListener("click", function () {
socket.emit("confirmed");
});
});
socket.on('foo', function() {
counter++;
document.getElementById("alert").innerHTML = "foos counter: " + counter;
});
</script>
</body>
</html>

ClientJade - Trouble executing jade.render()

I've run into a problem in the clientside code for a Node.js app I'm working on.
The idea behind this is to update the browser immediately as the socket receives an event.
This is the script block on the client side:
script(src='/scripts/jadeTemplate.js')
script(src='/socket.io/socket.io.js')
script(type='text/javascript')
var socket = io.connect();
socket.on('obj', function(obj) {
var newsItem = document.createElement("item");
jade.render(newsItem, 'objTemplate', { object: obj });
$('#newsfeed').prepend(newsItem);
alert(obj);
});
When the alert() is placed before the jade.render(), it alerts, but if inserted after, it doesn't execute (hence, I think it's a problem with the jade.render()).
This is objTemplate.jade, referred to in line 7:
p #{object}
// That's it.
And this is a relevant snippet from the app.js:
var server = dgram.createSocket('udp4');
server.bind(41234);
server.on('message', function(buf, rinfo) {
isOnline = true;
var message = buf.toString();
io.sockets.emit('obj', message);
});
UPDATE:
Here's a link to /public/scripts/jadeTemplate.js, which IMO is too long of a snippet for a question.
If I need to provide any more snippets or files let me know. :)
Your template doesn't want an attribute object, it wants obj. Try this:
socket.on('obj', function(obj) {
var newsItem = document.createElement("item");
jade.render(newsItem, 'objTemplate', { obj: obj }); // changed object to obj
$('#newsfeed').prepend(newsItem);
alert(obj);
});
http://jsfiddle.net/trevordixon/VeYBY/ shows it working. If you change the attribute back to object, you'll get a javascript error in the console.

Socket IO times out after some time of innactivity, doesn't work, why?

I am new to socket IO and all, I've been working with it for about the last month, but I have noticed over the time that if I let my website sit and not do anything for a small amount of time, (Im not sure how much), but it seems to timeout, and the events aren't called unless I reload the page. There must be a way to fix this?
my server code:
var io = require('socket.io').listen(4000);
var users = {};
io.disable('heartbeats');
////////////////USER CONNECTED
io.sockets.on('connection', function (socket) {
socket.emit('connected');
socket.on('session', function (session) {
///all my other functions here
});
});
then included on my page is:
<script>var socket = io.connect("http://<?php print $_SERVER["SERVER_NAME"]?>",
{port: 4000, 'reconnect': true,'reconnection delay': 1500});</script>
<script type="text/javascript" src="js/ws/data/data.js"></script>
data.js is where all of my socket io functions are for the user end.
Try removing this line:
io.disable('heartbeats');
See Configuring Socket.IO.

Resources