因为要选择不同客户端发送数据给他,remoteaddress & port 已经存在数据,需要发送时要指定远程的地址和端口(当然,数据库会实时更新客户的地址和端口),查手册socket.write 未提及 指定地址和端口的选项。
mysql.query('SELECT ipAddressCurrent,remotePortCurrent FROM Device WHERE uniqueID = "’+uid+’"’, function(err, fields) { var res = fields[0]; var clientip = res[‘ipAddressCurrent’]; var clientport = res[‘remotePortCurrent’]; c.write(“test”); });
由于 客户的 ip 和 port 已经 存在数据,发送数据给客户时,想直接用 node net 的模块 发送 socket.write(ipaddress:port,"data"); 查了很多资料未找到,socket.io,可以设置客户端标示,可以发指定的客户(相当于聊天室的私聊),但我想看net可否实现。
var io = require('socket.io').listen(888);
//用于记录所有的客户端
var user_coll = {};
io.sockets.on('connection', function (socket) {
//客户端连接成功则设置客户端标示
socket.on('set nickname', function (name) {
user_coll[name] = socket;
user_coll[name].set('username', name, function () { user_coll[name].emit('ready'); });
user_coll[name].on('publicmsg',function(data){
user_coll[name].get('username',function(err, name){
var msg ="public msg - "+ name + " say : "+data;
io.sockets.emit('usermsg',msg);
});
})
user_coll[name].on('privatemsg',function(data){
//console.log(JSON);return false;
var jsonData = eval(data);
user_coll[jsonData.sendTo].get('username',function(err,name){
var msg ="private msg - "+name +" say : "+jsonData.text;
user_coll[jsonData.sendTo].emit('usermsg',msg);
});
});
});
});
此socket非彼socket io.sockets.on('connection’, function (socket) { 此处的socket ≠ net模块的socket,两者一毛钱关系都没有。。。 要实现楼主所说的效果,要么放弃socket.io自己在socket协议层上做client和server,要么hack进socket.io的代码,同时修改socket.io的server端和client端的代码,以增加相关api。
API for no namespace:
var clients = io.sockets.clients();
var clients = io.sockets.clients('room'); // all users from room `room`
For a namespace
var clients = io.of('/chat').clients();
var clients = io.of('/chat').clients('room'); // all users from room `room`
=========================================================
io.sockets.on('connection',function(socket){
io.sockets.sockets['nickname'] = socket.id;
client.on("chat", function(data) {
var sock_id = io.sockets.sockets['nickname']
io.sockets.sockets[sock_id].emit("private", "message");
}); });
socket.io 有相关的方法。但我想用 node net 模块 。
客户端是浏览器socket.io,服务端想用socket直接发送数据,这样? 但是。。。socket.io本质上是http长连接,socket是tcp协议。除非hack进socket.io的代码,获取本次http连接底层的socket对象,否则根本就没办法进行tcp层面的通讯。经过千难万苦,获得此socket对象,socket.write(‘hello’)发送数据给客户端,客户端根本无法解析:大哥,你说的哪国语言?请你用socket.io协议说话。最终,还是要用socket.io那套玩意,这不是瞎折腾吗。。。
socket.write(‘hello’) 是发给 tcp 的客户端的。
浏览器 连接 http.js,
http.js 连接 server.js
server.js 连接 gps 客户端 (tcp通讯)
目前,我已经可以在浏览器器发送数据在server.js里显示(tcp数据来的)。
表达可能不清楚,请见谅。
message->http server(http.js)->tcp server(server.js)->gps client,问题是卡在最后一步, 如何将msg发送给某个gps client,即某个特定remote address &port的连接, 这样?(真心希望能将问题表述的更明确些,猜来猜去真伤脑细胞) 既然能指定客户端的ip&port,那么 server.js至少持有客户端socket对象的引用吧?因此server.js同时接受来自http.js和gps的连接,server.js是router角色?(给出的信息量太少,偶只能猜猜猜。。。)
假使上诉猜测正确,server.js的粗略实现大概如此
var net=require('net');
var user_coll=[];
net.createServer(function(socket){
/** 此处未考虑所谓的拼包,chunk可能不是一个完整的message**/
socket.on('data',function(chunk){
var msg=chunk.toString();
//parse message to find out which type of client?
var info=parse(msg);
if(info.from=='http.js'){ //come from http.js
var username=info.sendTo;
//query db by username, fetch ip&port?
var userInfo=queryUserInfo(username);
for(var i=0;i<user_coll.length;i++){
if(userInfo.remoteAddress==user_coll[i].remoteAddress
&& userInfo.remotePort==user_coll[i].remotePort){
user_coll[i].write('forwarded message');
}
}
}else{ //come from gps client
if(~user_coll.indexOf(socket)){
user_coll.append(socket);
}
//do more work....
}
});
function dispose(){
var index=user_coll.indexOf(socket);
if(~index){
console.log('%s disconneted',socket.remoteAddress);
user_coll.splice(index,1);
socket.removeAllListeners();
}
}
socket.on('end',dispose);
socket.on('close',dispose);
}).listen(8080);
(聊天数据格式未给出,下半部分编不下去了) 另外就楼主最初问题-能不能socket.write(ipaddress:port,"data"),偶的回答是:NO。node不存在类似的api,当然也能写个类似的方法
function socket_write(ipaddress,port,"data"){
var socket=net.conenct(port,ipaddress);
socket.write("data");
}
不过这应该不是楼主的本意吧。