NodeJS - net模块初探

简介


  net模块nodejs通讯功能实现的基础,nodejs中最常用的功能就是作为WebServer使用,建立服务器时使用的http.createServer就是在net.createServer方法的基础上建立的。

        前端最熟悉的http协议属于应用层协议,应用层的内容想要发送出去,还需要将消息逐层下发,通过传输层(tcp,udp),网际层(ip)和更底层的网络接口后才能被传输出去。net模块就是对分层通讯模型的实现。

   net模块中有两大主要抽象概念——net.Servernet.Socket

Socket
是对 TCP/IP 协议族的一种封装,是应用层与TCP/IP协议族通信的中间软件抽象层。它把复杂的TCP/IP协议族隐藏在Socket接口后面,对用户来说,一组简单的接口就是全部,让Socket去组织数据,以符合指定的协议。

        简单地说,net.Server实例可以监听一个端口(用于实现客户端TCP连接通讯)或者地址(用于实现IPC跨进程通讯);net.Socket实例可以建立一个套接字实例,它可以用来和server建立连接,连接建立后,就可以实现通讯了。

使用示例


下面贴出UE4的pixelStreaming中MatchMaker的服务发现代码,以供参考:

// server

const net = require('net');

function disconnect(connection) {
	console.log(`Ending connection to remote address ${connection.remoteAddress}`);
	connection.end();
}

const matchmaker = net.createServer((connection) => {	
	///console.log(`Connection: ${JSON.stringify(connection)}`);
	console.log(`-----------------Connection remote address ${connection.remoteAddress}`);

	connection.on('data', (data) => {
		try {
			message = JSON.parse(data);
			console.log(`> Recv Cirrus information from data: ${data.toString()}`);
		} catch(e) {
			console.log(`ERROR (${e.toString()}): Failed to parse Cirrus information from data: ${data.toString()}`);
			disconnect(connection);
			return;
		}
		if (message.type === 'connect') {
			// A Cirrus server connects to this Matchmaker server.
			cirrusServer = {
				address: message.address,
				port: message.port,
				numConnectedClients: 0
			};
			cirrusServers.set(connection, cirrusServer);
			console.log(`Cirrus server ${cirrusServer.address}:${cirrusServer.port} connected to Matchmaker`);
		} else if (message.type === 'clientConnected') {
			// A client connects to a Cirrus server.
			cirrusServer = cirrusServers.get(connection);
			cirrusServer.numConnectedClients++;
			console.log(`Client connected to Cirrus server ${cirrusServer.address}:${cirrusServer.port}`);
		} else if (message.type === 'clientDisconnected') {
			// A client disconnects from a Cirrus server.
			cirrusServer = cirrusServers.get(connection);
			cirrusServer.numConnectedClients--;
			console.log(`Client disconnected from Cirrus server ${cirrusServer.address}:${cirrusServer.port}`);
		} else {
			console.log('ERROR: Unknown data: ' + JSON.stringify(message));
			disconnect(connection);
		}
	});

	// A Cirrus server disconnects from this Matchmaker server.
	connection.on('error', () => {
		cirrusServers.delete(connection);
		console.log(`Cirrus server ${cirrusServer.address}:${cirrusServer.port} disconnected from Matchmaker`);
	});
});

matchmaker.listen(matchmakerPort, () => {
	console.log('Matchmaker listening on *:' + matchmakerPort);
});
// client

if (config.UseMatchmaker) {
	var matchmaker = new net.Socket();

	matchmaker.on('connect', function () {
		console.log(`Cirrus connected to Matchmaker ${matchmakerAddress}:${matchmakerPort}`);
		message = {
			type: 'connect',
			address: typeof serverPublicIp === 'undefined' ? '127.0.0.1' : serverPublicIp,
			port: httpPort
		};
		matchmaker.write(JSON.stringify(message));
	});

	matchmaker.on('error', (err) => {
		console.log(`Matchmaker connection error ${JSON.stringify(err)}`);
	});

	matchmaker.on('end', () => {
		console.log('Matchmaker connection ended');
	});

	matchmaker.on('close', (hadError) => {
		console.log(`Matchmaker connection closed (hadError=${hadError})`);
		reconnect();
	});

	// Attempt to connect to the Matchmaker
	function connect () {
		matchmaker.connect(matchmakerPort, matchmakerAddress);
	}

	// Try to reconnect to the Matchmaker after a given period of time
	function reconnect () {
		console.log(`Try reconnect to Matchmaker in ${matchmakerRetryInterval} seconds`)
		setTimeout(function () {
			connect();
		}, matchmakerRetryInterval * 1000);
	}

	connect();
}

// The Matchmaker will not re-direct clients to this Cirrus server if any client
// is connected.
function sendPlayerConnectedToMatchmaker () {
	if (!config.UseMatchmaker)
		return;

	message = {
		type: 'clientConnected'
	};
	matchmaker.write(JSON.stringify(message));
}

// The Matchmaker is interested when nobody is connected to a Cirrus server
// because then it can re-direct clients to this re-cycled Cirrus server.
function sendPlayerDisconnectedToMatchmaker () {
	if (!config.UseMatchmaker)
		return;

	message = {
		type: 'clientDisconnected'
	};
	matchmaker.write(JSON.stringify(message));
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值