【问题标题】:node.js + socket.io + recursively adding repliesnode.js + socket.io + 递归添加回复
【发布时间】:2016-10-17 14:03:25
【问题描述】:

我拼凑了一个网页,以通过其串行端口控制 Onkyo 接收器,其中使用了我主要在 stackexchange 上找到的几个不同示例的一部分。它运行良好,但我在下面的第一个链接中遇到了@user568109 突出显示的问题,我认为我已经“从您的路由中初始化了连接事件监听器”而不是全局。 (每次刷新网页时,发送的回复数量都会增加一。)问题是我看不到如何全局初始化它。我尝试删除该功能:

io.sockets.on('connection', function (socket) {......}

但留下 ....... 部分,正如在下面的第二个链接中成功完成的那样,但这对我的情况不起作用。有简单的解决方法吗?我是 node 和 javascript 的完全新手,所以我希望这对某人来说是显而易见的。

除了每次刷新网页时的额外回复外,它运行良好。 (除了初始化开关,单选按钮和音量滑块被正确初始化,但是一旦我把这个插座的东西整理好,我会试着解决这个问题)。 谢谢!

Socket.io emits duplicate data after browser refresh

node.js + socket.io - duplicate websocket writes?

这里是sn-p的代码:

var express = require('express');
app 		= express();
server 		= require('http').createServer(app);
io  		= require('socket.io').listen(server);
var SerialPort = require("serialport")
var serialPort = new SerialPort("/dev/ttyUSB0", { 
		baudRate: 9600,
		dataBits: 8,
		parity: 'none',
		stopBits: 1
  		}
	);
server.listen(8080);
app.use(express.static('public'));             
io.sockets.on('connection', function (socket) {
        socket.on('toOnkyo', function (data) {
                paramVal = data.value;
                var buf = new Buffer(16);                
				buf.write(paramVal, "utf-8");
                serialPort.write(buf);
				io.sockets.emit('toOnkyo', {value: paramVal});   
				});

		serialPort.on('data', function(data) {
				io.sockets.emit('onkyoReply', {value: data.toString().substr(0,7)});
				});
		
});
console.log("running");
body {
	text-align: center;
	margin-top: 50px;
	background: #50D0A0;
}

input[type=range]{
	-webkit-appearance: none;
	width: 80%;
}

input[type=range]::-webkit-slider-runnable-track {
	height: 10px;
	background: #ddd;
	border: none;
	border-radius: 3px;
}

input[type=range]::-webkit-slider-thumb {
	-webkit-appearance: none;
	border: none;
	height: 32px;
	width: 32px;
	border-radius: 50%;
	background: goldenrod;
	margin-top: -12px;
}

input[type=range]:focus {
	outline: none;
}

input[type=range]:focus::-webkit-slider-runnable-track {
	background: #ccc;
}
.radioLeft
{
    text-align:left;
}



.onoffswitch {
    position: relative; width: 90px;
    -webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
}
.onoffswitch-checkbox {
    display: none;
}
.onoffswitch-label {
    display: block; overflow: hidden; cursor: pointer;
    border: 2px solid #999999; border-radius: 20px;
}
.onoffswitch-inner {
    display: block; width: 200%; margin-left: -100%;
    transition: margin 0.3s ease-in 0s;
}
.onoffswitch-inner:before, .onoffswitch-inner:after {
    display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
    font-size: 14px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
    box-sizing: border-box;
}
.onoffswitch-inner:before {
    content: "ON";
    padding-left: 10px;
    background-color: #34A7C1; color: #FFFFFF;
}
.onoffswitch-inner:after {
    content: "OFF";
    padding-right: 10px;
    background-color: #EEEEEE; color: #999999;
    text-align: right;
}
.onoffswitch-switch {
    display: block; width: 18px; margin: 6px;
    background: #FFFFFF;
    position: absolute; top: 0; bottom: 0;
    right: 56px;
    border: 2px solid #999999; border-radius: 20px;
    transition: all 0.3s ease-in 0s; 
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
    margin-left: 0;
}
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
    right: 0px; 
}
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
        <title>Onkyo Controller</title>
        <meta name="viewport" content="width=400px" />
        <script src="socket.io/socket.io.js"></script>
        <link rel="stylesheet" href="style.css">
  </head>
  <body>

Sent:		<span id="sliderVolText"></span><br>
Reply:		<span id="replyTextHex"></span>
(Decimal:	<span id="replyText10"></span>)<br>
Mode:		<span id="modeText"></span><br>
PowerText:	<span id="powerText"></span><br>
Power:		<span id="power"></span><br>
onoffText:	<span id="onoffText"></span><br>
onoff:		<span id="onoff"></span>  

	<script>
	function setCheckedValue(radioObj, newValue) {
		if(!radioObj)
			return;
		var radioLength = radioObj.length;
		if(radioLength == undefined) {
			radioObj.checked = (radioObj.value == newValue.toString());
			return;
		}
		for(var i = 0; i < radioLength; i++) {
			radioObj[i].checked = false;
			if(radioObj[i].value == newValue.toString()) {
				radioObj[i].checked = true;
			}
		}
	}
	</script>

	<form class="onoffswitch" >
		<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="myonoffswitch"  onclick="showOnoff(checked)">
		<label class="onoffswitch-label" for="myonoffswitch">
		<span class="onoffswitch-inner"></span>
		<span class="onoffswitch-switch"></span>
		</label>
	</form>

	<form name="modeForm" method="get" action="" onsubmit="return false;">
		<p>   <label for="mode0"><input type="radio" value="0x00" name="modeForm" id="mode0" onclick="showMode(this.value)"> Stereo</label>
		&nbsp;<label for="mode1"><input type="radio" value="0x01" name="modeForm" id="mode1" onclick="showMode(this.value)"> Direct</label>
		&nbsp;<label for="mode2"><input type="radio" value="0x0C" name="modeForm" id="mode2" onclick="showMode(this.value)"> All Ch stereo</label>
		&nbsp;<label for="mode3"><input type="radio" value="0x42" name="modeForm" id="mode3" onclick="showMode(this.value)"> THX Cinema</label>
		&nbsp;<label for="mode4"><input type="radio" value="0x84" name="modeForm" id="mode4" onclick="showMode(this.value)"> PLllx THX Cinema</label>
		&nbsp;<label for="mode5"><input type="radio" value="0x11" name="modeForm" id="mode5" onclick="showMode(this.value)"> Pure</label>
	</form>

	<form name="slideForm" method="get" action="" onsubmit="return false;">
		<input type="range" id= "inputSlider" min="0" max="100" value="vol" step="1" oninput="showVolume(this.value)" />
	</form>

	<br><br>
	<div class="results"></div>
	<script type="text/javascript">
		var socket = io.connect();
		var ctrlType = "";
			socket.on('toOnkyo', function (data) {
				ctrlType = data.value.toString().substr(2,3);
				if (ctrlType == "MVL" && !(data.value.toString().substr(5,4)=="QSTN")){
					document.getElementById("inputSlider").value =  parseInt(data.value.toString().substr(5,2),16);
					document.getElementById("sliderVolText").innerHTML = data.value;
				}
				if (ctrlType == "LMD" && !(data.value.toString().substr(5,4)=="QSTN")){
					document.getElementById("mode").value =  parseInt(data.value.toString().substr(5,2),16);
					document.getElementById("modeText").innerHTML = data.value;
				}
				if (ctrlType == "PWR" && !(data.value.toString().substr(5,4)=="QSTN")	){
					document.getElementById("power").value =  parseInt(data.value.toString().substr(5,2),16);
					document.getElementById("powerText").innerHTML = data.value;
				}
				if (ctrlType == "PWR" && !(data.value.toString().substr(5,4)=="QSTN")	){
					document.getElementById("onoff").value =  parseInt(data.value.toString().substr(5,2),16);
					document.getElementById("onoffText").innerHTML = data.value;
				}
			});
            socket.on('onkyoReply', function (data) {
                var done = false;
				ctrlType = data.value.toString().substr(2,3);
				document.getElementById("replyTextHex").innerHTML = data.value;
				document.getElementById("replyText10").innerHTML = parseInt(data.value.toString().substr(5,2),16);
				if (ctrlType == "LMD"){
					setCheckedValue(document.forms['modeForm'].elements['modeForm'],"0x"+data.value.toString().substr(5,2));
				}
				if (ctrlType == "PWR"){
					var val = parseInt(data.value.toString().substr(5,2),16);
					setCheckedValue(document.forms['powerForm'].elements['powerForm'],"0x"+data.value.toString().substr(5,2));
				}
				if (ctrlType == "MVL" && done == false){
					document.getElementById("inputSlider").value = parseInt(data.value.toString().substr(5,2),16);
					document.querySelector('.results').innerHTML = parseInt(data.value.toString().substr(5,2),16);
					done = true;						
				}
			});

			function showVolume(newValue) {						
		        document.getElementById("sliderVolText").innerHTML="\!1MVL"+("0" + Number(newValue).toString(16)).slice(-2)+"\r\n";
                socket.emit('toOnkyo', { value: "\!1MVL"+("0" + Number(newValue).toString(16)).slice(-2)+"\r\n" });
			}

			function showMode(newValue) {
				document.getElementById("modeText").innerHTML="\!1LMD"+("0" + Number(newValue).toString(16)).slice(-2)+"\r\n";
                socket.emit('toOnkyo', { value: "\!1LMD"+("0" + Number(newValue).toString(16)).slice(-2)+"\r\n" });
			}

			function showOnoff(newValue) {
				document.getElementById("onoffText").innerHTML="\!1PWR"+("0" + Number(newValue).toString(16)).slice(-2)+"\r\n";
				socket.emit('toOnkyo', { value: "\!1PWR"+("0" + Number(newValue).toString(16)).slice(-2)+"\r\n" });
			}

			socket.emit('toOnkyo', { value: "\!1PWRQSTN"+"\r\n" });
			socket.emit('toOnkyo', { value: "\!1LMDQSTN"+"\r\n" });
			socket.emit('toOnkyo', { value: "\!1MVLQSTN"+"\r\n" });
			
	</script>
  </body>
</html>

【问题讨论】:

    标签: node.js socket.io


    【解决方案1】:

    根据 Ian Wooten 的博客找到了解决方案:

    http://www.ianwootten.co.uk/2011/07/04/maintaining-references-to-sockets-with-express-and-socket-io/

    太棒了!

    server.listen(8080);
    app.use(express.static('public'));             
    var paramVal = 0;
    var countRep = 0;
    var countSend = 0;
    var buf = new Buffer(16);
    var global_socket;
    
    io.sockets.on('connection', function (socket) {
    		global_socket = socket;
            global_socket.on('toOnkyo', function (data) {
                    paramVal = data.value;
    				buf.write(paramVal, "utf-8");
                    serialPort.write(buf);
    				console.log(paramVal.toString().substr(0,7) + " (" + parseInt(paramVal.toString().substr(5,2),16) + ")\r\n");				
                    global_socket.emit('toOnkyo', {value: paramVal});   
    				console.log('new'+paramVal);
    				countSend=countSend+1;
    				console.log('count send '+ countSend);
    				
    				});
    });
    				serialPort.on('data', function(data) {
    				console.log('data received: ' + data.toString().substr(0,7) + " (" + parseInt(data.toString().substr(5,2),16) + ")");
    				global_socket.emit('onkyoReply', {value: data.toString().substr(0,7)});
    				countRep=countRep+1;
    				console.log('count '+ countRep);
    				});
    
    console.log("running");

    【讨论】:

      猜你喜欢
      • 2013-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-03
      • 2021-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多