- Home /
Node.js Problem
In my game ,i am using Node.js for server and client communication . This code works on localhost , but on real server. Some Datas are missing on real server-client communication .
Sample code
Servire side Data sending
var reply0 = new Object();
reply0.message = "WaitRoom";
reply0.your_room_id = rooms_uniqueid;
// // // //console.log(" reply0.messsage : "+ reply0.message);
stream.write(JSON.stringify(reply0) + "\0");
clearInterval(players_list[rooms_uniqueid]['PlayersListDelay']);
players_list[rooms_uniqueid]['PlayersListDelay'] = setInterval( function(){
clearInterval(players_list[rooms_uniqueid]['PlayersListDelay']);
PlayersList(rooms_uniqueid); // for listing player details in room
},msgDelayTime); // delay for message
Client Side data reading
try
{
serverStream = tcpClient.GetStream ();
int buffSize = 0;
buffSize = tcpClient.ReceiveBufferSize;
byte [] inStream = new byte[buffSize];
serverStream.Read (inStream,0,(int)buffSize);
string returnData = System.Text.Encoding.ASCII.GetString(inStream);
Decide_Action(returnData);
}
catch (Exception e)
{
c_global.isClientDisconnectOn = true;
}
Any one have solution.
Answer by KpjComp · Oct 16, 2014 at 07:48 AM
Hi, I use node for a lot of server side stuff. I've found using Express really helps when creating server side Rest API's. Using tcp directly you need to remember a little bit more housekeeping, eg. buffSize = tcpClient.ReceiveBufferSize, that line you can't assume is a whole message, If your message is greater than the MTU size it could be sent in multiple blocks. Localhost most likely has a larger MTU than ethernet, and that might explain why it fails on ethernet. Another advantage of using Express with it's HTTP protocol, it's nice for debugging, and putting an SSL layer on top is very easy.
If you still want to use TCP directly, I would suggest you send the length of your message first, and then the message so you can keep reading until you have received all data, then process your message.
Edit: Ok.. I've now created a simple Chat Application, The code for both is now here and I've included a Zip link text with the full example. In the Zip is two directories, one directory contains the unity project, the other contains a node express app. To save on zipping Express into the zip, go into this directory and type ->
npm install express
And then to start the server.
node index
The meat of the code I'll also paste here. In unity assign the C# script to say a dummy object, and then from your UI, assign the username / msg / textfield & button, and you should be good to go..
Node bit.
'use strict';
var express = require('express'),
events = require('events'),
app = express(),
eventer = new events.EventEmitter(),
comments = [];
//save having to doing json decoding in unity, do it here
function commentsTxt() {
var l, r = '', c;
for (l = 0; l < comments.length; l += 1) {
c = comments[l];
r += '<b>' + c.name + '</b> ' + c.msg + '\r\n';
}
return r;
}
/* the list has a wait option, this will be usefull
for long polling */
app.get('/list', function (req, res) {
if (req.query.wait !== undefined) {
eventer.once('newComment', function () {
res.end(commentsTxt());
});
} else {
res.end(commentsTxt());
}
});
app.get('/say', function (req, res) {
if (comments.length >= 50) {
comments.splice(0, 1);
}
comments.push(req.query);
eventer.emit('newComment');
console.log(req.query);
res.json({saved: true});
});
app.listen(3000);
And the unity C# script
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
public class ChatController : MonoBehaviour {
public InputField fldUser;
public InputField fldMsg;
public Button btSend;
public Text textOutput;
private string urlapi = "http://localhost:3000/";
// Use this for initialization
IEnumerator Start () {
fldUser.value = "Player " + Random.Range(1, 100);
btSend.onClick.AddListener(sendMsg);
fldMsg.onSubmit.AddListener(sendMsg2);
textOutput.text = "Connecting..";
WWW www = new WWW(urlapi + "list");
yield return www;
textOutput.text = www.text;
StartCoroutine(longPolling());
}
IEnumerator longPolling () {
WWW www = new WWW(urlapi + "list?wait");
yield return www;
textOutput.text = www.text;
StartCoroutine(longPolling());
}
void sendMsg2(string msg) {
StartCoroutine(sendMsgNow());
}
void sendMsg() {
StartCoroutine(sendMsgNow());
}
IEnumerator sendMsgNow() {
if (fldMsg.value == "") {
fldMsg.ActivateInputField();
yield break;
}
string url = urlapi +
"say?name=" + WWW.EscapeURL(fldUser.value) +
"&msg=" + WWW.EscapeURL(fldMsg.value);
WWW www = new WWW(url);
yield return www;
fldMsg.value = "";
fldMsg.ActivateInputField();
}
}
As you can see, there is not a lot of code.. It's not a very complicated chat app deliberately to make it easy to follow.. Hope this helps to get you started..
Could you give me some sample code and please explain about Express . Is there any tutorial available for Unity-Node.js ?
Express website is here -> http://expressjs.com/ And a really simple example would be http://expressjs.com/4x/api.html , ins$$anonymous$$d of res.send("hello world!"), you would return your json with res.json(mygamedata). Once this is setup you can use the Web API from Unity. -> http://docs.unity3d.com/ScriptReference/WWW.html to send messages. If you want the client to have constant fast updates from the server you could also make use of long-polling, basically this is just the client constantly requesting in a loop and checking for timeouts. I used to do a lot of direct TCP(winsock) program$$anonymous$$g, and I have to say it's way easer to do it this way, and much more flexible in the long run, and the HTTP protocol overhead is $$anonymous$$imal nowadays, especially with keep-alives.
How to read data from server.Could you give sample code for both server side and client side (Reading and sending messages)
Hi, I'm currently at work. But tonight I'll see if I can knock up a Demo. To keep the Demo really simple an idea is were the server would create a set of Labels, and as each user clicks one a counter would increase and then the clients would see this change. Would that be enough to get started?
Another option also is using Unity's built in multi-player framework, here I believe it's very simple to create objects that serialize between network players.
Your answer
Follow this Question
Related Questions
Client with authority can't send information to server 0 Answers
Error: "A client which was not in the connected player list disconnected. ???" 1 Answer
Need help getting "Server Reconciliation" to work. 0 Answers
How to secure (encrypt) tcp client server connection? 1 Answer
How to test Unity's new networking layer in separate game instances? 0 Answers