play chess with socket.io and uci - node.js

I want to create a webapp where you can play against a UCI-Chessengine. I found https://github.com/imor/uci which works nice on commandline. So I "only" need a websocket to evaluate the moves.
But I'm not able to get it running... I tried (based on the uci-example):
io.sockets.on('connection',function(socket){
socket.on('start', function(data) {
var uci = new UCI();
var game = new Chess();
uci.on('ready', function () {
//Start a new 10 minute game with engine as black, use the first found
//engine and the first found polyglot book
uci.startNewGame(uci.getAvailableEngines()[0], 'black', 10,
uci.getAvailableBooks()[0]);
}).on('newgame', function () {
console.log("A new 10 minute game has started.");
console.log("Enter your moves in algebraic notation. E.g. e2e4<Enter>");
console.log(game.ascii());
}).on('moved', function (move) {
game.move(move);
console.log(move.from + move.to + (move.promotion ? move.promotion : ''));
console.log(game.ascii());
}).on('error', function (message) {
console.log('Error:' + message);
}).on('exit', function (message) {
console.log('Exiting:' + message);
}).on('gameends', function (result, reason) {
console.log('Game ends with result ' + result + ' because ' + reason);
uci.shutdown();
process.exit();
});
})
socket.on('m',function(data){
uci.move(data.move);
});
});
Starting the game is working: socket.emit('start',{"bar":"foo"})
but when I try to make a move with socket.emit('m':"e2e4") it does not know the uci.move
That's okay cause it's defined within socket.on('start')... so he can't know it, but I'm not able to get it running. I've tried some stupid ideas, for example putting the socket.on('m') into the socket.on('start')...
Can somebody help me with this? How can I send moves to the created uci-connection? Or is this not possible?
Thank you very much.

Try moving the var uci up in the scope hierarchy.
io.sockets.on('connection',function(socket){
var uci;
socket.on('start', function(data) {
uci = new UCI();
var game = new Chess();
...
})
socket.on('m',function(data){
uci.move(data.move);
});
});

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?

Getting a progress for an FTP-upload with node

I have an Electron app which uploads a dropped file to a predefined server with node-ftp. The upload works like a charm, but despite reading a couple of suggestions I cannot figure out how to get information on the actual progress for a progress-bar.
My upload-code so far:
var ftp = new Client();
let uploadfile = fs.createReadStream(f.path);
let newname = uuid(); //some function I use for renaming
ftp.on('ready', function () {
ftp.put(uploadfile, newname, function (err) {
if (err) throw err;
ftp.end();
});
});
c.connect({user: 'test', password: 'test'});
I always stumble across monitoring the 'data' event, but could not find out how or where to access it (as you can see I'm quite new to JavaScript).
Got it. I found the answer in streams with percentage complete
With my code changed to
var ftp = new Client();
let uploadfile = fs.createReadStream(f.path);
let newname = uuid(); //some function I use for renaming
ftp.on('ready', function() {
uploadfile.on('data', function(buffer) {
var segmentLength = buffer.length;
uploadedSize += segmentLength;
console.log("Progress:\t" + ((uploadedSize/f.size*100).toFixed(2) + "%"));
});
ftp.put(uploadfile, newname, function(err) {
if (err) throw err;
ftp.end();
});
});
c.connect({user: 'test', password: 'test'});
I get the percentage uploaded in console. From here it's only a small step to a graphical output.
on client side you can create a byte count for your upload stream (http://www.experts.exchange.com/questions/24041115/upload-file-on-ftp-with-progressbar-and-time-left.html)
set lower limit of the progressbar to 0
set upper limit to file length of upload file
feed the progress bar with the byte count
(http://www.stackoverflow.com/questions/24608048/how-do-i-count-bytecount-in-read-method-of-inputstream)
maybe you can use npm like stream-meter (https://www.npmjs.com/package/stream-meter) or progress-stream (https://www.npmjs.com/package/progress-stream) and pipe your file stream through to feed the progressbar. i am not sure about that because i do not know the internals of the npms. in progress-stream is a function transferred() that would fit exactly
a very accurate way is to have code on the server that gives feedback to the browser (http://www.stackoverflow.com/questions/8480240/progress-bar-for-iframe-uploads)

Unknown method process.openStdin()

I'm trying to pipe grep results into nodejs script. I've found, that I should receive data from process.stdin.
Also I've found several ways to work with stdin. But they are different and I can't find all information about it. I know four ways (first 3 start with var data = ""):
1) Most popular in search results
process.stdin.resume();
process.stdin.setEncoding( 'utf8' );
process.stdin.on('data', function(chunk) { data += chunk; });
process.stdin.on('end', function() { console.log('data: ' + data); });
2) Looks like the first one, but with unknown function process.openStdin()
var stdin = process.openStdin();
stdin.on('data', function(chunk) { data += chunk; });
stdin.on('end', function() { console.log('data: ' + data); });
3) In the documentation I've read that calling stdin.resume() changes stdin to 'old type'. So if we didn't called 'resume' - we can use 'readable' event
process.stdin.setEncoding('utf8');
process.stdin.on('readable', function() { data += process.stdin.read(); });
process.stdin.on('end', function() { console.log('data: ' + data); });
4) Use module readline. It is very usefull as long as grep results are in mutiple lines and there I don't need to split received data by myself. But for a long time i couldn't understand why all information is piped to stdout directly. Then i i've found that we can pass empty object instead of process.stdout while creating interface and data wouldn't piped to output.
var readline = require('readline'),
//rl = readline.createInterface(process.stdin, process.stdout);
rl = readline.createInterface(process.stdin, {});
rl.on('line', function(data) { console.log('line: ' + data); });
5) My own variant. Use another module 'split' - it allows to read from stream and devide data into chuks by specified symbol (\r?\n by default). I used it to work with socket and as soon as stdin is also readable stream - we can use it here.
var split = require('split');
process.stdin.setEncoding('utf8');
process.stdin.pipe(split()).on('data', function(data) { console.log('line: ' + data); });
My question is "What is process.openStdin();????"
I've searched every page in google, but didn't found any documentation on this function!
Also while searching I've discovered, that official documentation for nodejs is ugly - not mentioned since which version methods are available, no detailed description on many objects/methods, no user comments. And this method (openStdin) - exists and works, but nowhere discribed! WTF???
While writing the question I've found the answer :)
It is in source code of nodejs:
process.openStdin = function() {
process.stdin.resume();
return process.stdin;
};
But I wonder, why is it not described in documentation? If it is a function for private use only, why is it used by many people, who wrote about working with stdin?

send JSON data to Unity from Node.js

I asked this question on the official forum but I guess I don't have enough rep there to be taken seriously :O
I'm using Unity3D free.
Has anyone used https://www.assetstore.unity3d.com/en/#!/content/21721 with success? This plugin actually came the closest to working (I also tried this and this but they don't work for me).
I contacted the author but haven't got a reply yet, so was wondering if someone had made this work?
(edit: I would like to point out that I don't mind buying some other plugin if you have used it and found it easy/useful to communicate with your Node.js server via SocketIO - so please recommend)
Concretely, here's my problem with it:
I cant find a way to send JSON data to Unity from Node.js as it keeps getting an error.
I tried numerous ways, and this is one of them:
io.on('connection', function(socket){
console.log('a user connected');
var data ='{"email":"some#email.com","pass":"1234"}';
var dataJson = JSON.stringify(data);
console.dir(dataJson);
socket.emit('newResults', dataJson);
console.log('server emited newResults');
socket.on('fromClient', function(data){
console.log("got msg from client");
console.dir(data);
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
In Unity3D I use the following function to intercept this:
public void HandleNewResults(SocketIOEvent e){
Debug.Log(string.Format("[name: {0}, data: {1}]", e.name, e.data));
Debug.Log (new JSONObject (e.data));
}
but it crashes (it catches the error signal) at this point with (when debugging is turned on) this message:
SocketComm:TestError(SocketIOEvent) (at Assets/_Scripts/SocketComm.cs:58)
SocketIO.SocketIOComponent:EmitEvent(SocketIOEvent) (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:400)
SocketIO.SocketIOComponent:EmitEvent(String) (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:392)
SocketIO.SocketIOComponent:OnError(Object, ErrorEventArgs) (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:382)
WebSocketSharp.Ext:Emit(EventHandler`1, Object, ErrorEventArgs) (at Assets/SocketIO/WebsocketSharp/Ext.cs:992)
WebSocketSharp.WebSocket:error(String) (at Assets/SocketIO/WebsocketSharp/WebSocket.cs:1011)
WebSocketSharp.WebSocket:Send(String) (at Assets/SocketIO/WebsocketSharp/WebSocket.cs:1912)
SocketIO.SocketIOComponent:EmitPacket(Packet) (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:309)
SocketIO.SocketIOComponent:EmitClose() (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:299)
SocketIO.SocketIOComponent:Close() (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:184)
SocketIO.SocketIOComponent:OnApplicationQuit() (at Assets/SocketIO/Scripts/SocketIO/SocketIOComponent.cs:164)
Can you please shed some light on how to aproach this problem?
I'm using Unity3D free.
But SocketIO needs Unity Pro. If you want to use native .NET sockets.
Unity Pro is required in order to build using .NET sockets. You may
use a replacement package if you don't want to use native sockets.
You can use Good ol' Sockets.It's usable for sockets.
I used such code:
socket.emit('event_name', {"email":"some#email.com","pass":"1234"});
I do not know if it right. The function in unity is:
public void TestBoop (SocketIOEvent e)
{
Debug.Log ("[SocketIO] Boop received: " + e.name + "--" + e.data);
);
}
And output is:
[SocketIO] Boop received: boop--{"email":"some#email.com","pass":"1234"}
Perhaps it does't right at all but the result at least comes to unity
Make these changes:
io.on('connection', function(socket){
console.log('a user connected');
var data ='{"email":"some#email.com","pass":"1234"}';
var dataJson = JSON.stringify(data);
console.dir(dataJson);
console.log('server emited newResults');
socket.on('beep', function(){
socket.emit('boop', {'boop': dataJson});
console.log("got msg from client");
console.dir(data);
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
this is will work.

Restarting nodejs ntwitter twitter stream with different track keywords

var twitter = require('ntwitter');
// Configure twitter
var keywords = ['hello', 'world'];
twit.stream('statuses/filter', {'track':keywords.join(',')}, function(stream) {
stream.on('data', function (data) {
console.log(data);
});
stream.on('end', function (response) {
console.log("\n====================================================");
console.log("DESTROYING");
console.log("====================================================\n");
});
setTimeout(function(){
stream.destroy();
}, 60000);
});
I'm new to nodejs. What is the best way to stop this and start it again with but a different set of keywords.
I can destroy() the stream and then create a new one. But is there anyway I can just change the track keywords without disconnecting?
I'm quite noob, so maybe this way it's not a good one and it's wasting resources, but I still don't know how to check it, so I will drop it here and hope that someone skilled told us if it's OK or it's wrong, and the most important, why?.
The way is to put the tw.stream call, inside a function and call that function with the array of words you want to track. It will start tracking new words, and stop tracking removed words:
// Array to store the tracked words
var TwitWords = [];
// Tracker function
function TrackWords(array){
tw.stream('statuses/filter',{track:array},function(stream){
stream.on('data',function(data){
console.log(data.text);
});
});
}
// Add word
function AddTwitWord(word){
if(TwitWords.indexOf(word)==-1){
TwitWords.push(word);
TrackWords(TwitWords);
}
}
// Remove word
function RemoveTwitWord(word){
if(TwitWords.indexOf(word)!=-1){
TwitWords.splice(TwitWords.indexOf(word),1);
TrackWords(TwitWords);
}
}
I hope it's ok, because it's the only way I found.

Resources