Socket.io TypeError:fn.bind不是函数

Socket.io TypeError:fn.bind不是函数,socket.io,webrtc,Socket.io,Webrtc,我试图通过与webRTC书的实时通信来实现webRTC,我得到了以下错误。我使用的是socket.io 1.7.3版本 ***Server.js*** C:\Users\raghav\node_modules\socket.io-adapter\index.js:196 if (fn) process.nextTick(fn.bind(null, null, sids)); ^ TypeError: fn.bind is not

我试图通过与webRTC书的实时通信来实现webRTC,我得到了以下错误。我使用的是socket.io 1.7.3版本

***Server.js***

C:\Users\raghav\node_modules\socket.io-adapter\index.js:196
  if (fn) process.nextTick(fn.bind(null, null, sids));
                              ^

TypeError: fn.bind is not a function
    at Adapter.clients (C:\Users\raghav\node_modules\socket.io-adapter\index.js:196:31)
    at Namespace.clients (C:\Users\raghav\node_modules\socket.io\lib\namespace.js:256:16)
    at Socket.<anonymous> (C:\Users\raghav\WebstormProjects\NewsRoom\js\server.js:22:37)
    at emitOne (events.js:96:13)
    at Socket.emit (events.js:188:7)
    at C:\Users\raghav\node_modules\socket.io\lib\socket.js:503:12
    at _combinedTickCallback (internal/process/next_tick.js:73:7)
    at process._tickCallback (internal/process/next_tick.js:104:9)

Process finished with exit code 1

**webRTc.HTML**

Failed to load resource: net::ERR_CONNECTION_REFUSED
GET http://localhost:8181/socket.io/?EIO=3&transport=polling&t=LkCudeu net::ERR_CONNECTION_REFUSED
***Server.js***
C:\Users\raghav\node\u modules\socket.io adapter\index.js:196
if(fn)process.nextTick(fn.bind(null,null,sids));
^
TypeError:fn.bind不是函数
位于Adapter.clients(C:\Users\raghav\node\u modules\socket.io Adapter\index.js:196:31)
位于Namespace.clients(C:\Users\raghav\node\u modules\socket.io\lib\Namespace.js:256:16)
在插座上。(C:\Users\raghav\webstoreprojects\NewsRoom\js\server.js:22:37)
在emitOne(events.js:96:13)
在Socket.emit(events.js:188:7)
在C:\Users\raghav\node\u modules\socket.io\lib\socket.js:503:12
at _combinedTickCallback(内部/流程/下一步_tick.js:73:7)
在进程中。_tick回调(内部/process/next_tick.js:104:9)
进程已完成,退出代码为1
**webRTc.HTML**
未能加载资源:网络::错误\u连接\u被拒绝
得到http://localhost:8181/socket.io/?EIO=3&transport=polling&t=LkCudeu 网络::错误连接被拒绝
下面是我使用的代码

webRTC.html

<!DOCTYPE html>
<html>rag
<head>
    <title>Very simple WebRTC application with a Node.js signaling server</title>
</head>
<body>
<div id='mainDiv'>
    <table border="1" width="100%">
        <tr>
            <th>
                Local video
            </th>
            <th>
                Remote video
            </th>
        </tr>
        <tr>
            <td>
                <video id="localVideo" autoplay></video>
            </td>
            <td>
                <video id="remoteVideo" autoplay></video>
            </td>
        </tr>
        <tr>
            <td align="center">
<textarea rows="4" cols="60"
          id="dataChannelSend" disabled
          placeholder="This will be enabled once
the data channel is up...">
</textarea>
            </td>
            <td align="center">
<textarea rows="4" cols="60"
          id="dataChannelReceive" disabled>
</textarea>
            </td>
        </tr>
        <tr>
            <td align="center">
                <button id="sendButton" disabled>Send</button>
            </td>
            <td></td>
        </tr>
    </table>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/adapterjs/0.14.1/adapter.min.js"></script>
<script src='js/completeNodeClientWithDataChannel.js'></script>
</body>
</html>

破布
带有Node.js信令服务器的非常简单的WebRTC应用程序
本地视频
远程视频
发送
completeNodeClientWithDataChannel.js

'use strict';
// Look after different browser vendors' ways of calling the getUserMedia()
// API method:
// Opera --> getUserMedia
// Chrome --> webkitGetUserMedia
// Firefox --> mozGetUserMedia
navigator.getUserMedia = navigator.getUserMedia ||
    navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
// Clean-up function:
// collect garbage before unloading browser's window
window.onbeforeunload = function(e){
    hangup();
}
// Data channel information
var sendChannel, receiveChannel;
var sendButton = document.getElementById("sendButton");
var sendTextarea = document.getElementById("dataChannelSend");
var receiveTextarea = document.getElementById("dataChannelReceive");
// HTML5 <video> elements
var localVideo = document.querySelector('#localVideo');
var remoteVideo = document.querySelector('#remoteVideo');
// Handler associated with Send button
sendButton.onclick = sendData;
// Flags...
var isChannelReady = false;
var isInitiator = false;
var isStarted = false;
// WebRTC data structures
// Streams
var localStream;
var remoteStream;
// PeerConnection
var pc;
// PeerConnection ICE protocol configuration (either Firefox or Chrome)
var pc_config = webrtcDetectedBrowser === 'firefox' ?
    {'iceServers':[{'url':'stun:23.21.150.121'}]} : // IP address
    {'iceServers': [{'url': 'stun:stun.l.google.com:19302'}]};
var pc_constraints = {
    'optional': [
        {'DtlsSrtpKeyAgreement': true}
    ]};
var sdpConstraints = {};
// Let's get started: prompt user for input (room name)
var room = prompt('Enter room name:');
// Connect to signaling server
var socket = io.connect("http://131.95.31.179:8181");
// Send 'Create or join' message to singnaling server
if (room !== '') {
    console.log('Create or join room', room);
    socket.emit('create or join', room);
}
// Set getUserMedia constraints
var constraints = {video: true, audio: true};
// From this point on, execution proceeds based on asynchronous events...
// getUserMedia() handlers...
function handleUserMedia(stream) {
    localStream = stream;
    attachMediaStream(localVideo, stream);
    console.log('Adding local stream.');
    sendMessage('got user media');
}
function handleUserMediaError(error){
    console.log('navigator.getUserMedia error: ', error);
}
// Server-mediated message exchanging...
// 1. Server-->Client...
// Handle 'created' message coming back from server:
// this peer is the initiator
socket.on('created', function (room){
    console.log('Created room ' + room);
    isInitiator = true;
// Call getUserMedia()
    navigator.getUserMedia(constraints, handleUserMedia, handleUserMediaError);
    console.log('Getting user media with constraints', constraints);
    checkAndStart();
});
// Handle 'full' message coming back from server:
// this peer arrived too late :-(
socket.on('full', function (room){
    console.log('Room ' + room + ' is full');
});
// Handle 'join' message coming back from server:
// another peer is joining the channel
socket.on('join', function (room){
    console.log('Another peer made a request to join room ' + room);
    console.log('This peer is the initiator of room ' + room + '!');
    isChannelReady = true;
});
// Handle 'joined' message coming back from server:
// this is the second peer joining the channel
socket.on('joined', function (room){
    console.log('This peer has joined room ' + room);
    isChannelReady = true;
// Call getUserMedia()
    navigator.getUserMedia(constraints, handleUserMedia, handleUserMediaError);
    console.log('Getting user media with constraints', constraints);
});
// Server-sent log message...
socket.on('log', function (array){
    console.log.apply(console, array);
});
// Receive message from the other peer via the signaling server
socket.on('message', function (message){
    console.log('Received message:', message);
    if (message === 'got user media') {
        checkAndStart();
    } else if (message.type === 'offer') {
        if (!isInitiator && !isStarted) {
            checkAndStart();
        }
        pc.setRemoteDescription(new RTCSessionDescription(message));
        doAnswer();
    } else if (message.type === 'answer' && isStarted) {
        pc.setRemoteDescription(new RTCSessionDescription(message));
    } else if (message.type === 'candidate' && isStarted) {
        var candidate = new RTCIceCandidate({sdpMLineIndex:message.label,
            candidate:message.candidate});
        pc.addIceCandidate(candidate);
    } else if (message === 'bye' && isStarted) {
        handleRemoteHangup();
    }
});
// 2. Client-->Server
// Send message to the other peer via the signaling server
function sendMessage(message){
    console.log('Sending message: ', message);
    socket.emit('message', message);
}
// Channel negotiation trigger function
function checkAndStart() {
    if (!isStarted && typeof localStream != 'undefined' && isChannelReady) {
        createPeerConnection();
        isStarted = true;
        if (isInitiator) {
            doCall();
        }
    }
}
// PeerConnection management...
function createPeerConnection() {
    try {
        pc = new RTCPeerConnection(pc_config, pc_constraints);
        pc.addStream(localStream);
        pc.onicecandidate = handleIceCandidate;
        console.log('Created RTCPeerConnnection with:\n' +
            ' config: \'' + JSON.stringify(pc_config) + '\';\n' +
            ' constraints: \'' + JSON.stringify(pc_constraints) + '\'.');
    } catch (e) {
        console.log('Failed to create PeerConnection, exception: ' + e.message);
        alert('Cannot create RTCPeerConnection object.');
        return;
    }
    pc.onaddstream = handleRemoteStreamAdded;
    pc.onremovestream = handleRemoteStreamRemoved;
    if (isInitiator) {
        try {
// Create a reliable data channel
            sendChannel = pc.createDataChannel("sendDataChannel",
                {reliable: true});
            trace('Created send data channel');
        } catch (e) {
            alert('Failed to create data channel. ');
            trace('createDataChannel() failed with exception: ' + e.message);
        }
        sendChannel.onopen = handleSendChannelStateChange;
        sendChannel.onmessage = handleMessage;
        sendChannel.onclose = handleSendChannelStateChange;
    } else { // Joiner
        pc.ondatachannel = gotReceiveChannel;
    }
}
// Data channel management
function sendData() {
    var data = sendTextarea.value;
    if(isInitiator) sendChannel.send(data);
    else receiveChannel.send(data);
    trace('Sent data: ' + data);
}
// Handlers...
function gotReceiveChannel(event) {
    trace('Receive Channel Callback');
    receiveChannel = event.channel;
    receiveChannel.onmessage = handleMessage;
    receiveChannel.onopen = handleReceiveChannelStateChange;
    receiveChannel.onclose = handleReceiveChannelStateChange;
}
function handleMessage(event) {
    trace('Received message: ' + event.data);
    receiveTextarea.value += event.data + '\n';
}
function handleSendChannelStateChange() {
    var readyState = sendChannel.readyState;
    trace('Send channel state is: ' + readyState);
// If channel ready, enable user's input
    if (readyState == "open") {
        dataChannelSend.disabled = false;
        dataChannelSend.focus();
        dataChannelSend.placeholder = "";
        sendButton.disabled = false;
    } else {
        dataChannelSend.disabled = true;
        sendButton.disabled = true;
    }
}
function handleReceiveChannelStateChange() {
    var readyState = receiveChannel.readyState;
    trace('Receive channel state is: ' + readyState);
// If channel ready, enable user's input
    if (readyState == "open") {
        dataChannelSend.disabled = false;
        dataChannelSend.focus();
        dataChannelSend.placeholder = "";
        sendButton.disabled = false;
    } else {
        dataChannelSend.disabled = true;
        sendButton.disabled = true;
    }
}
// ICE candidates management
function handleIceCandidate(event) {
    console.log('handleIceCandidate event: ', event);
    if (event.candidate) {
        sendMessage({
            type: 'candidate',
            label: event.candidate.sdpMLineIndex,
            id: event.candidate.sdpMid,
            candidate: event.candidate.candidate});
    } else {
        console.log('End of candidates.');
    }
}
// Create Offer
function doCall() {
    console.log('Creating Offer...');
    pc.createOffer(setLocalAndSendMessage, onSignalingError, sdpConstraints);
}
// Signaling error handler
function onSignalingError(error) {
    console.log('Failed to create signaling message : ' + error.name);
}
// Create Answer
function doAnswer() {
    console.log('Sending answer to peer.');
    pc.createAnswer(setLocalAndSendMessage, onSignalingError, sdpConstraints);
}
// Success handler for both createOffer()
// and createAnswer()
function setLocalAndSendMessage(sessionDescription) {
    pc.setLocalDescription(sessionDescription);
    sendMessage(sessionDescription);
}
// Remote stream handlers...
function handleRemoteStreamAdded(event) {
    console.log('Remote stream added.');
    attachMediaStream(remoteVideo, event.stream);
    console.log('Remote stream attached!!.');
    remoteStream = event.stream;
}
function handleRemoteStreamRemoved(event) {
    console.log('Remote stream removed. Event: ', event);
}
// Clean-up functions...
function hangup() {
    console.log('Hanging up.');
    stop();
    sendMessage('bye');
}
function handleRemoteHangup() {
    console.log('Session terminated.');
    stop();
    isInitiator = false;
}
function stop() {
    isStarted = false;
    if (sendChannel) sendChannel.close();
    if (receiveChannel) receiveChannel.close();
    if (pc) pc.close();
    pc = null;
    sendButton.disabled=true;
}
“严格使用”;
//注意不同浏览器供应商调用getUserMedia()的方式
//API方法:
//Opera-->getUserMedia
//Chrome-->webkitGetUserMedia
//Firefox-->mozGetUserMedia
navigator.getUserMedia=navigator.getUserMedia||
navigator.webkitGetUserMedia | | navigator.mozzetusermedia;
//清理功能:
//在卸载浏览器窗口之前收集垃圾
window.onbeforeunload=函数(e){
挂断();
}
//数据通道信息
var发送通道、接收通道;
var sendButton=document.getElementById(“sendButton”);
var sendTextarea=document.getElementById(“dataChannelSend”);
var receiveTextarea=document.getElementById(“dataChannelReceive”);
//HTML5元素
var localVideo=document.querySelector('#localVideo');
var remoteVideo=document.querySelector(“#remoteVideo”);
//与发送按钮关联的处理程序
sendButton.onclick=sendData;
//旗帜。。。
var isChannelReady=false;
var isInitiator=false;
var isStarted=假;
//WebRTC数据结构
//溪流
var-localStream;
远程流;
//对等连接
var-pc;
//PeerConnection ICE协议配置(Firefox或Chrome)
var pc_config=webrtctedbrowser==='firefox'?
{'iceServers':[{'url':'stun:23.21.150.121'}]}://IP地址
{'iceServers':[{'url':'stun:stun.l.google.com:19302'}]};
变量pc_约束={
“可选”:[
{'DtlsSrtpKeyAgreement':true}
]};
var sdpConstraints={};
//让我们开始:提示用户输入(房间名称)
var room=prompt('输入房间名称:');
//连接到信令服务器
变量套接字=io.connect(“http://131.95.31.179:8181");
//向singnaling服务器发送“创建或加入”消息
如果(房间!=''){
控制台日志(“创建或加入文件室”,文件室);
socket.emit('create或join',房间);
}
//设置getUserMedia约束
var约束={video:true,audio:true};
//从现在开始,执行将基于异步事件进行。。。
//getUserMedia()处理程序。。。
函数handleUserMedia(流){
localStream=stream;
attachMediaStream(本地视频、流);
log('添加本地流');
sendMessage('got user media');
}
函数handleUserMediaError(错误){
日志('navigator.getUserMedia错误:',错误);
}
//服务器中介的消息交换。。。
// 1. 服务器-->客户端。。。
//处理从服务器返回的“已创建”消息:
//该对等方是发起方
插座打开('已创建'),功能(房间){
console.log('创建的房间'+房间);
isInitiator=true;
//调用getUserMedia()
getUserMedia(约束、handleUserMedia、handleUserMediaError);
log('获取带有约束的用户媒体',约束);
checkAndStart();
});
//处理从服务器返回的“完整”消息:
//这位同行来得太晚了:-(
插座打开(“满”,功能(房间){
console.log('房间'+房间+'已满');
});
//处理从服务器返回的“加入”消息:
//另一个对等方正在加入该频道
插座开('join',功能(房间){
log('另一个对等方请求加入房间'+房间);
console.log('此对等方是文件室“+文件室+!”的发起方);
isChannelReady=true;
});
//处理从服务器返回的“已加入”消息:
//这是加入通道的第二个对等方
插座上的('连接',功能(房间){
console.log('该对等方已加入房间'+房间);
isChannelReady=true;
//调用getUserMedia()
getUserMedia(约束、handleUserMedia、handleUserMediaError);
log('获取带有约束的用户媒体',约束);
});
//服务器已发送日志消息。。。
socket.on('log',函数(数组){
console.log.apply(控制台,数组);
});
//通过信令服务器从另一个对等方接收消息
socket.on('message',函数(message){
console.log('收到的消息:',消息);
如果(消息=='已获得用户媒体'){
checkAndStart();
}else if(message.type==='offer'){
如果(!isInitiator&!isStarted){
checkAndStart();
}
pc.setRemoteDescription(新的RTCSessionDescription(消息));
doAnswer();
}else if(message.type==='answer'&&isstart){
pc.setRemoteDescription(新的RTCSessionDescription(消息));
}else if(message.type==='candidate'&&isStarted){
变量
var static = require('node-static');
var http = require('http');
// Create a node-static server instance
var file = new(static.Server)();
// We use the http module’s createServer function and
// rely on our instance of node-static to serve the files
var app = http.createServer(function (req, res) {
    file.serve(req, res);
}).listen(8181);
// Use socket.io JavaScript library for real-time web applications
var io = require('socket.io').listen(app);
// Let's start managing connections...
io.sockets.on('connection', function (socket){
// Handle 'message' messages
    socket.on('message', function (message) {
        log('S --> got message: ', message);
// channel-only broadcast...
        socket.broadcast.to(message.channel).emit('message', message);
    });
// Handle 'create or join' messages
    socket.on('create or join', function (room) {
        var numClients = io.sockets.clients(room).length;
        log('S --> Room ' + room + ' has ' + numClients + ' client(s)');
        log('S --> Request to create or join room', room);
// First client joining...
        if (numClients == 0){
            socket.join(room);
            socket.emit('created', room);
        } else if (numClients == 1) {
// Second client joining...
            io.sockets.in(room).emit('join', room);
            socket.join(room);
            socket.emit('joined', room);
        } else { // max two clients
            socket.emit('full', room);
        }
    });
    function log(){
        var array = [">>> "];
        for (var i = 0; i < arguments.length; i++) {
            array.push(arguments[i]);
        }
        socket.emit('log', array);
    }
});
var numClients = io.sockets.clients(room).length;
    io.of('/').in(room).clients(function(error,clients){
        var numClients=clients.length;
    });