- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
今天又要问这个问题了。
我正在处理代码以一对一连接到允许群组对话的代码。不用拐弯抹 Angular ,我有这段代码:
CallToUsers = function(connection) {
var connection = connection;
var isChannelReady;
var isInitiator = false;
var isStarted = false;
var servers = null;
var localStream = connection.getStream();
var localStreams = [];
var localConnection;
var turnReady;
var remoteStreams = [];
var remoteStream;
var pcConfig = {
'iceServers': [{
'url': 'stun:stun.l.google.com:19302'
}]
};
var pcConstraints = {
'optional': [{
'DtlsSrtpKeyAgreement': true
}]
};
var sdpConstraints = {
'mandatory': {
'OfferToReceiveAudio': true,
'OfferToReceiveVideo': true
}
};
var room;
var socket = io.connect();
var divElement = document.createElement('div');
divElement.setAttribute('id', 'remotesVideo');
document.body.appendChild(divElement);
var createRoom = function(room) {
room = room;
if(room !== '') {
console.log('Create or join to room', room);
socket.emit('create or join', room);
}
socket.on('created', function(room) {
console.log('Created room ' + room);
isInitiator = true;
});
/*socket.on('full', function(room) {
console.log('Room' + room + ' is full');
});*/
socket.on('join', function(room) {
console.log('Another peer made request to join ' + room);
isChannelReady = true;
});
socket.on('joined', function(room) {
console.log('User joined to room ' + room);
isChannelReady = true;
});
socket.on('log', function(array) {
console.log.apply(console, array);
});
};
var sendMessage = function(message) {
console.log('Client sending a message: ', message);
socket.emit('message', message);
};
window.onbeforeunload = function(e){
sendMessage('bye');
};
var startCall = function() {
sendMessage('got user media');
if(isInitiator) {
maybeStart();
}
socket.on('message', function(message) {
console.log('Client received a message: ' + message);
if(message === 'got user media') {
maybeStart();
} else if(message.type === 'offer') {
if(!isInitiator && !isStarted) {
maybeStart();
}
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].setRemoteDescription(new RTCSessionDescription(message));
}
doAnswer();
} else if(message.type === 'answer' && isStarted) {
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].setRemoteDescription(new RTCSessionDescription(message));
}
} else if(message.type === 'candidate' && isStarted) {
var candidate = new RTCIceCandidate({
sdpMLineIndex: message.label,
candidate: message.candidate
});
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].addIceCandidate(candidate);
}
} else if(message === 'bye' && isStarted) {
handleRemoteEndCall();
}
});
//if(location.hostname != 'localhost') {
//requestTurn('https://computeengineondemand.appspot.com/turn?username=41784574&key=4080218913');
//}
};
var maybeStart = function() {
if(!isStarted && typeof localStream != 'undefined' && isChannelReady) {
createPeerConnection();
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].addStream(localStream);
}
isStarted = true;
if(isInitiator) {
doCall();
}
}
};
var createPeerConnection = function() {
try {
localConnection = new RTCPeerConnection(pcConfig, pcConstraints);
localConnection.onicecandidate = handleIceCandidate;
localConnection.onaddstream = handleRemoteStreamAdded;
localConnection.onremovestream = handleRemoteStreamRemoved;
localStreams.push(localConnection);
console.log('Created RTCPeerConnection');
} catch(e) {
console.log('exception ' + e.message);
return;
}
};
var handleIceCandidate = function(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');
}
};
var handleRemoteStreamAdded = function(event) {
console.log('Remote stream added');
var newVideo = document.createElement('video');
newVideo.setAttribute('id', Math.floor((Math.random() * 1000) + 1));
newVideo.muted = false;
divElement.appendChild(newVideo);
attachMediaStream(newVideo, event.stream);
remoteStream = event.stream;
remoteStreams.push(remoteStream);
};
var handleRemoteStreamRemoved = function(event) {
console.log('Delete');
};
var handleCreateOfferError = function(event) {
console.log('createOffer() error: ' + e);
}
var setLocalAndSendMessage = function(sessionDescription) {
sessionDescription.sdp = preferOpus(sessionDescription.sdp);
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].setLocalDescription(sessionDescription);
}
sendMessage(sessionDescription);
};
var doCall = function() {
console.log('Start call');
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].createOffer(setLocalAndSendMessage, handleCreateOfferError);
}
};
var doAnswer = function() {
console.log('Sending answer');
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].createAnswer(setLocalAndSendMessage, null, sdpConstraints);
}
};
var endCall = function() {
console.log('Hanging up');
isStarted = false;
for(var i = 0; i < localStreams.length; i++) {
localStreams[i].close();
localStreams[i] = null;
}
sendMessage('bye');
};
var handleRemoteEndCall = function() {
};
var requestTurn = function(turnUrl) {
var turnExists = false;
for(var i in pcConfig.iceServers) {
if(pcConfig.iceServers[i].url.substr(0, 5) === 'turn:') {
turnExists = true;
turnReady = true;
break;
}
}
if(!turnExists) {
console.log('Getting TURN server from ', turnUrl);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4 && xhr.status === 200) {
var turnServer = JSON.parse(xhr.responseText);
console.log('Got TURN server: ', turnServer);
pc_config.iceServers.push({
'url': 'turn:' + turnServer.username + '@' + turnServer.turn,
'credential': turnServer.password
});
turnReady = true;
}
};
xhr.open('GET', turnUrl, true);
xhr.send();
}
};
var preferOpus = function(sdp) {
var sdpLines = sdp.split('\r\n');
var mLineIndex;
for(var i = 0; i < sdpLines.length; i++) {
if(sdpLines[i].search('m=audio') !== -1) {
mLineIndex = i;
break;
}
}
if(mLineIndex === null) {
return sdp;
}
for(i = 0; i < sdpLines.length; i++) {
if(sdpLines[i].search('opus/48000') !== -1) {
var opusPayload = extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
if(opusPayload) {
sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], opusPayload);
}
break;
}
}
sdpLines = removeCN(sdpLines, mLineIndex);
sdp = sdpLines.join('\r\n');
return sdp;
};
var extractSdp = function(sdpLine, pattern) {
var result = sdpLine.match(pattern);
return result && result.length === 2 ? result[1] : null;
};
var setDefaultCodec = function(mLine, payload) {
var elements = mLine.split(' ');
var newLine = [];
var index = 0;
for(var i = 0; i < elements.length; i++) {
if(index === 3) {
newLine[index++] = payload;
}
if(elements[i] !== payload) {
newLine[index++] = elements[i];
}
}
return newLine.join(' ');
};
var removeCN = function(sdpLines, mLineIndex) {
var mLineElements = sdpLines[mLineIndex].split(' ');
for(var i = sdpLines.length - 1; i >= 0; i--) {
var payload = extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);
if(payload) {
var cnPos = mLineElements.indexOf(payload);
if(cnPos !== -1) {
mLineElements.splice(cnPos, 1);
}
sdpLines.splice(i, 1);
}
}
sdpLines[mLineIndex] = mLineElements.join(' ');
return sdpLines;
};
return {
startCall: startCall,
endCall: endCall,
createRoom: createRoom
};
};
虽然两个用户之间的对话运行良好,但是当添加另一个成员时,它不再连接到其他两个对等点,尽管我看到的日志很清楚地连接到同一个房间。
在控制台中,没有错误。
有没有人愿意帮忙?
@编辑
如果需要,我也会添加服务器代码:
var static = require('node-static');
var http = require('http');
var file = new(static.Server)();
var app = http.createServer(function (req, res) {
file.serve(req, res);
}).listen(2017);
var io = require('socket.io').listen(app);
io.sockets.on('connection', function (socket){
function log(){
var array = [">>> "];
for (var i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', function (message) {
log('Got message: ', message);
socket.broadcast.emit('message', message); // should be room only
});
socket.on('create or join', function (room) {
var numClients = io.sockets.clients(room).length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room', room);
if (numClients == 0){
socket.join(room);
socket.emit('created', room);
} else {
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
}
socket.emit('emit(): client ' + socket.id + ' joined room ' + room);
socket.broadcast.emit('broadcast(): client ' + socket.id + ' joined room ' + room);
});
});
最佳答案
终于解决了问题。写作 session 的一般规则,所有同行都连接到的地方是这样的:每个新来的人都扮演回答者的 Angular 色,并在与所有向他发送报价的报价建立联系后,开始充当报价者(第一个同行除外,这始终是报价)。 @Mert Koksal,感谢您的关注。
关于javascript - session 、WebRTC 的点对点返工,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22696720/
我正在尝试实现这个协议(protocol):http://en.wikipedia.org/wiki/Chord_(peer-to-peer ) 我从中了解到的是,加入“圆圈”的每个节点都放置在圆圈内
我对 java 中的 cometd 很陌生。 我对 java 中的 cometd 更感兴趣,但是当我用 google 搜索它时,我几乎找不到一个链接这是 cometd 链接,文档中不清楚。 有人可以发
什么是编写 XNA 点对点游戏的最佳方式而不必使用要求游戏的两个玩家都具有 XBOX Gold 成员(member)资格的 Windows Live 东西 我还需要一些客户端/服务器功能,但这还不是很
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
假设我有 2 部手机,彼此相距 50 米,我想从手机 A 向手机 B 发送一个非常小的数据包,而不使用与蜂窝塔的任何通信。 为了简单起见,我想构建一个应用程序,为同一半径(同一区域)的 2 部手机实现
我听说过点对点内存传输并阅读了一些关于它的内容,但无法真正理解与标准 PCI-E 总线传输相比它的速度有多快。 我有一个使用多个 GPU 的 CUDA 应用程序,我可能对 P2P 传输感兴趣。我的问题
我从Android website中发现了这一点他们告诉我当前的 API使开发人员能够为 Wifi 点对点进行一些编程仅适用于 Android 4.0(API 级别 14)。 这是真的吗?我的意思是我
我正在为网页编写一个简单的 javascript 游戏。我将使用 tidesdk 将其转换为桌面。我想让不同机器上的玩家无需通过服务器进行通信。 一般来说这可能吗?这是套接字??您是否有使用 Java
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 7 年前。 Improve this q
我想在我的 iPhone 应用程序中加入 Paypal 作为点对点选项来回馈 friend 。然而,当我在网上搜索 Paypal iOS 时,它说我现在应该使用 Braintree。 它非常易于使用并
关闭。这个问题需要更多focused .它目前不接受答案。 想改进这个问题吗? 更新问题,使其只关注一个问题 editing this post . 关闭 4 年前。 Improve this qu
我正在寻找一种使用 p2p 将客户端(网络浏览器)连接到服务器(没有外部 IP)的方法。 作为客户端语言,我想使用 javascript。 我正在阅读有关 WebRTC 点对点的信息,但我不知道它是否
我在 .NET 3.5 中使用 WCF 来实现对等网络应用程序。我使用 PNRP 解析对等节点。 IGlobalStoreServiceContract 是我的契约(Contract),如下所示, [
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
是否有任何已知的方法可以在不使用专用中央服务器的情况下找到对等点? 即:如果我有对等方断开并重新连接到互联网但每次都获得一个新的 IP 地址,并且我想连接到他们而不设置专用服务器进行注册。 我正在考虑
我正在尝试将 Paypal 的自适应支付 API 集成到我的应用程序中,将只使用点对点交易,但我无法做任何与点对点支付相关的事情。我尝试使用这个工具 from Paypal 但我仍然没有取得任何成功。
我正在编写用于交换文本消息的点对点(它不应该有服务器 - 这是一项任务)程序。这是一个非常小的聊天。只是消息,没有别的。这是我第一次练习 Boost::Asio,因此我有一些问题。 正如我所说,我的聊
很难说出这里问的是什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或言辞激烈,无法以目前的形式合理回答。如需帮助澄清此问题以便可以重新打开,visit the help center . 9年前关闭
我想使用 Python 和 Ubuntu 在两台计算机之间双向传输音频,最好使用 H.323 我看过 pjsip,但只能看到一种连接到 SIP 服务器的方式,而不是简单的点对点系统。 谁能指出我正确的
我有两个使用 vert.x EventBus 进行通信的 Java 类。 我有一个 Productor.java 类: package TP1; import io.vertx.core.Abstra
我是一名优秀的程序员,十分优秀!