why I cant connect with username and password with SOCKS5 like
username:password#ip:port, i can with HTTP, but cant with SOCKS5
doneusername:password#ip:port, i can with HTTP, but cant with SOCKS5
done
SOCKS5 ; username:password#ip:port
Attempting connection to ws://ip:port
Connecting to: ws://ip:port
net.js:928
throw new RangeError('port should be >= 0 and < 65536: ' + port);
^
RangeError: port should be >= 0 and < 65536: NaN
at lookupAndConnect (net.js:928:13)
at Socket.connect (net.js:905:5)
at Socket.connect (net.js:868:37)
var WebSocket = require('ws');
var valid_player_pos = null;
var reconnect = false;
var suicide_targets = null;
var socket = require('socket.io-client')(config.feederServer);
socket.on('pos', function(data) {
valid_player_pos = data;
//console.log(data);
});
socket.on('cmd', function(data) {
console.log(data);
if (data.name == "split") {
for (bot in bots) {
bots[bot].client.split();
}
} else if (data.name == "eject") {
for (bot in bots) {
bots[bot].client.eject();
}
} else if (data.name == "connect_server") {
if (data.ip == null) {
return;
}
if (data.ip == "") {
return;
}
for (bot in bots) {
bots[bot].client.disconnect();
}
bots = {};
game_server_ip = data.ip;
console.log("client requested bots on: " + game_server_ip);
setTimeout(function() {
startFeederBotOnProxies();
}, 1000);
} else if(data.name == "reconnect_server") {
reconnect = true;
if (data.ip == null) {
return;
}
if (data.ip == "") {
return;
}
for (bot in bots) {
bots[bot].client.disconnect();
}
bots = {};
game_server_ip = data.ip;
console.log("client requested bots on: " + game_server_ip);
}
});
socket.on('force-login', function(data) {
console.log(data);
if (data == "server-booted-up") {
return;
}
socket.emit("login", {
"uuid": config.client_uuid,
"type": "server"
});
});
fs = require('fs');
var HttpsProxyAgent = require('https-proxy-agent');
var Socks = require('socks');
function getRandomLine(filename) {
var fs = require('fs');
var lines = fs.readFileSync(filename).toString().split("\n");
line = lines[Math.floor(Math.random() * lines.length)];
return line
}
//object of bots
var bots = {};
bot_count = 0;
var fs = require('fs');
var lines = fs.readFileSync(config.proxies).toString().split("\n");
var url = require('url');
var game_server_ip = null;
function createAgent(ip,type) {
data = ip.split(":");
return new Socks.Agent({
proxy: {
ipaddress: data[0],
port: parseInt(data[1]),
type: parseInt(type)
}}
);
}
var proxy_mode = "HTTP";
function startFeederBotOnProxies() {
for (proxy_line in lines) {
if(lines[proxy_line].trim() == "#HTTP"){
proxy_mode = "HTTP";
}else if(lines[proxy_line].trim() == "#SOCKS4"){
proxy_mode = "SOCKS4";
}else if(lines[proxy_line].trim() == "#SOCKS5"){
proxy_mode = "SOCKS5";
}
if (lines[proxy_line][0] == "#" || lines[proxy_line].length < 3) {
continue;
}
//usefull for testing single proxies
if (process.argv[3] != null && proxy_line != process.argv[3]) {
continue;
}
proxy = "http://" + lines[proxy_line];
proxy_single = lines[proxy_line];
console.log(proxy_mode + " ; " + proxy_single);
try {
var opts = url.parse(proxy);
if (proxy != null) {
if(proxy_mode=="HTTP"){
agent = HttpsProxyAgent(opts);
}else if(proxy_mode=="SOCKS4"){
agent = createAgent(lines[proxy_line],4);
}else if(proxy_mode=="SOCKS5"){
agent = createAgent(lines[proxy_line],5);
}
} else {
var agent = null;
}
if (lines[proxy_line] == "NOPROXY") {
agent = null;
}
console.log("Attempting connection to " + game_server_ip);
for (i = 0; i < config.botsPerIp; i++) {
if(bot_count<config.maxBots){
bot_count++;
bots[bot_count] = new FeederBot(bot_count, agent, bot_count, game_server_ip);
}
}
} catch (e) {
console.log('Error occured on startup: ' + e);
}
}
}
console.log("ogar-feeder-bot started! Join a game in Chrome with the Userscript installed.");
console.log("Press CTRL + C to stop this script.");
From all of discussions I get that the problem with Your createAgent.
So use this code and be happy (:
function createAgent(connectionString, type) {
var type = parseInt(type || 5);
var ipParts = connectionString.split('#'); // splitting user:pass#host:port
var host, port, username, password;
switch(ipParts.length) {
case 3 : // somebody#somewhere.com:somepassword#proxy.com:1080
var credentials = (ipParts[0]+'#'+ipParts[1]).split(':'); // yusolokuji#leeching.net:luquitas
username = credentials[0]; // somebody#somewhere.com
password = credentials[1]; // somepassword
var hostParts = ipParts[2].split(':'); // proxy.com:1080
host = hostParts[0];
port = hostParts[1] || 1080;
break;
case 2 : // somebody:somepassword#proxy.com:1080
var credentials = ipParts[0].split(':'); // somebody:somepassword
username = credentials[0]; // somebody
password = credentials[1]; // somepassword
var hostParts = ipParts[1].split(':'); // proxy.com:1080
host = hostParts[0];
port = hostParts[1] || 1080;
break;
case 1 : // proxy.com:1080
ipParts = ipParts[0].split(':');
host = ipParts[0];
port = ipParts[1];
break;
}
var config = {
proxy: {
ipaddress: host,
port: parseInt(port),
type: type
}
};
if(type == 5) {
config.proxy.authentication = {
username: username,
password: password
};
}
if(type == 4) {
config.proxy.user_id = username;
}
return new Socks.Agent(config);
}
Related
I need to send data from a custom form to Zoho. I'm looking at the native javascript request in their documentation here.
https://www.zoho.com/crm/developer/docs/api/v2/insert-records.html
var listener = 0;
class InsertRecordsAPI {
async insertRecords() {
var url = "https://www.zohoapis.com/crm/v2/Leads"
var parameters = new Map()
var headers = new Map()
var token = {
clientId:"1000.NPY9M1V0XXXXXXXXXXXXXXXXXXXF7H",
redirectUrl:"http://127.0.0.1:5500/redirect.html",
scope:"ZohoCRM.users.ALL,ZohoCRM.bulk.read,ZohoCRM.modules.ALL,ZohoCRM.settings.ALL,Aaaserver.profile.Read,ZohoCRM.org.ALL,profile.userphoto.READ,ZohoFiles.files.ALL,ZohoCRM.bulk.ALL,ZohoCRM.settings.variable_groups.ALL"
}
var accesstoken = await new InsertRecordsAPI().getToken(token)
headers.set("Authorization", "Zoho-oauthtoken " + accesstoken)
var requestMethod = "POST"
var reqBody = {"data":[{"Last_Name":"Lead_changed","Email":"newcrmapi#zoho.com","Company":"abc","Lead_Status":"Contacted"},{"Last_Name":"New Lead","Email":"newlead#zoho.com","Company":"abc","Lead_Status":"Contacted"}],"trigger":["approval","workflow","blueprint"]}
var params = "";
parameters.forEach(function(value, key) {
if (parameters.has(key)) {
if (params) {
params = params + key + '=' + value + '&';
}
else {
params = key + '=' + value + '&';
}
}
});
var apiHeaders = {};
if(headers) {
headers.forEach(function(value, key) {
apiHeaders[key] = value;
});
}
if (params.length > 0){
url = url + '?' + params.substring(0, params.length - 1);
}
var requestObj = {
uri : url,
method : requestMethod,
headers : apiHeaders,
body : JSON.stringify(reqBody),
encoding: "utf8",
allowGetBody : true,
throwHttpErrors : false
};
var result = await new InsertRecordsAPI().makeAPICall(requestObj);
console.log(result.status)
console.log(result.response)
}
async getToken(token) {
if(listener == 0) {
window.addEventListener("storage", function(reponse) {
if(reponse.key === "access_token" && (reponse.oldValue != reponse.newValue || reponse.oldValue == null)){
location.reload();
}
if(reponse.key === "access_token"){
sessionStorage.removeItem("__auth_process");
}
}, false);
listener = 1;
if(sessionStorage.getItem("__auth_process")) {
sessionStorage.removeItem("__auth_process");
}
}
["granted_for_session", "access_token","expires_in","expires_in_sec","location","api_domain","state","__token_init","__auth_process"].forEach(function (k) {
var isKeyExists = localStorage.hasOwnProperty(k);
if(isKeyExists) {
sessionStorage.setItem(k, localStorage[k]);
}
localStorage.removeItem(k);
});
var valueInStore = sessionStorage.getItem("access_token");
var tokenInit = sessionStorage.getItem("__token_init");
if(tokenInit != null && valueInStore != null && Date.now() >= parseInt(tokenInit) + 59 * 60 * 1000){ // check after 59th minute
valueInStore = null;
sessionStorage.removeItem("access_token");
}
var auth_process = sessionStorage.getItem("__auth_process");
if ((valueInStore == null && auth_process == null) || (valueInStore == 'undefined' && (auth_process == null || auth_process == "true"))) {
var accountsUrl = "https://accounts.zoho.com/oauth/v2/auth"
var clientId;
var scope;
var redirectUrl;
if(token != null) {
clientId = token.clientId;
scope = token.scope;
redirectUrl = token.redirectUrl;
}
var fullGrant = sessionStorage.getItem("full_grant");
var grantedForSession = sessionStorage.getItem("granted_for_session");
if(sessionStorage.getItem("__token_init") != null && ((fullGrant != null && "true" == full_grant) || (grantedForSession != null && "true" == grantedForSession))) {
accountsUrl += '/refresh';
}
if (clientId && scope) {
sessionStorage.setItem("__token_init", Date.now());
sessionStorage.removeItem("access_token");
sessionStorage.setItem("__auth_process", "true");
window.open(accountsUrl + "?" + "scope" + "=" + scope + "&"+ "client_id" +"=" + clientId + "&response_type=token&state=zohocrmclient&redirect_uri=" + redirectUrl);
["granted_for_session", "access_token","expires_in","expires_in_sec","location","api_domain","state","__token_init","__auth_process"].forEach(function (k) {
var isKeyExists = localStorage.hasOwnProperty(k);
if(isKeyExists){
sessionStorage.setItem(k, localStorage[k]);
}
localStorage.removeItem(k);
});
valueInStore = sessionStorage.getItem("access_token");
}
}
if(token != null && valueInStore != 'undefined'){
token.accessToken = valueInStore;
}
return token.accessToken;
}
async makeAPICall(requestDetails) {
return new Promise(function (resolve, reject) {
var body, xhr, i;
body = requestDetails.body || null;
xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open(requestDetails.method, requestDetails.uri, true);
for (i in requestDetails.headers) {
xhr.setRequestHeader(i, requestDetails.headers[i]);
}
xhr.send(body);
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
resolve(xhr);
}
}
})
}
}
I need to send dynamic data and I'm a little fuzzy on how to use the async functions and populate the reqBody variable.
I have tried things like
makeAPICall(myjson);
.then((data) => { console.log(data)})
But I'm not getting anything returned. Any response is welcome. My thanks in advance.
I have a problem when using await in a for loop. Every time it hits the await funtion it executes it fine, but it stops loping through the rest of the array that is looping through. I'm using nodejs with axios to send http request to a restAPI. The function that is in the api is big. So I thought maby that is the problem but it wasn't. Also the api uses its own await functions to, but that wasn't the problem either(As far as I know).
Here is my code for the request
var files = await globPromise("assets/series/**/*.json");
var json = null;
var file = null;
var series = [];
for (i = 0; i < files.length; i++) {
file = files[i];
var raw = fs.readFileSync(file);
json = JSON.parse(raw);
if (json.type === "series") {
try {
var userId = null;
if (req.user == null) {
userId = req.query.userid;
} else {
userId = req.user.id;
}
const response = await axios.get("http://" + host + "/series/info/" + json.id + "?userid=" + userId);
series.push(JSON.parse(response.data));
} catch (error) {
console.log(error);
series.push(json);
}
}
}
res.json(JSON.stringify(series));
});
And also the api side:
app.get('/series/info/:id', async(req, res) => {
var files = await globPromise("assets/series/**/*.json");
var json = null;
var file = null;
for (i = 0; i < files.length; i++) {
file = files[i];
var raw = fs.readFileSync(file);
json = JSON.parse(raw);
if (json.type === "series" && json.id === req.params.id) {
break;
}
json = null;
}
let path = pathFs.dirname(file) + "/";
try {
var seriesFiles = await fsPromise.readdir(path);
var latestWatchedVideo = null;
var latestWatchedTime = null;
var latestWatchTime = null;
var latestWatchDuration = null;
var seasonCount = 0;
var seasons = [];
for (i = 0; i < seriesFiles.length; i++) {
seriesFile = seriesFiles[i];
if (fs.lstatSync(path + "/" + seriesFile).isDirectory()) {
if (!seriesFile.startsWith("s")) {
continue;
}
seasonCount++;
try {
var videoFiles = await fsPromise.readdir(path + "/" + seriesFile + "/");
var videos = [];
for (let i = 0; i < videoFiles.length; i++) {
const video = videoFiles[i];
if (video.endsWith(".json")) {
var rawVideo = fs.readFileSync(path + "/" + seriesFile + "/" + video);
videoJson = JSON.parse(rawVideo);
const query = util.promisify(con.query).bind(con);
var userId = null;
if (req.user == null) {
userId = req.query.userid;
} else {
userId = req.user.id;
}
var results = await query(`SELECT * FROM watched WHERE video_id = "${videoJson.id}" AND user_id = "${userId}"`);
if (results.length > 0) {
var updated = JSON.parse(JSON.stringify(results[0].updated));
var duration = JSON.parse(JSON.stringify(results[0].duration));
var time = JSON.parse(JSON.stringify(results[0].time));
if (latestWatchedVideo == null) {
latestWatchedVideo = videoJson.id;
latestWatchedTime = updated;
latestWatchTime = time;
latestWatchDuration = duration;
} else {
if (latestWatchedTime < updated) {
latestWatchedVideo = videoJson.id;
latestWatchedTime = updated;
latestWatchTime = time;
latestWatchDuration = duration;
}
}
}
videos.push(videoJson);
}
}
function compare(a, b) {
if (a.episode < b.episode) {
return -1;
}
if (a.episode > b.episode) {
return 1;
}
return 0;
}
videos.sort(compare);
seasons.push({
season: seasonCount,
title: seriesFile.replace("s" + seasonCount, ""),
videos: videos
});
} catch (error) {
console.log(error);
}
}
}
json.seasonCount = seasonCount;
json.seasons = seasons;
json.latestWatchDuration = latestWatchDuration;
json.latestWatchTime = latestWatchTime;
json.latestWatchedVideo = latestWatchedVideo;
json.latestWatchedTime = latestWatchedTime;
res.json(JSON.stringify(json));
} catch (error) {
console.log(error);
}
});
Is there something (important) about await and async that I've missed?
Edit: my problem is that is loops fine through the first item and the await is working fine too, but it stops the loop and executes the next lines of code like there are no other items in my array.
Solved: I tried using the for/of and it works now. I don't know whats is so different between de default for and this one but it works!
Situation:
I want to create a multithread script where I load a list of IPs + account information with a CSV.
I load the data and call a function where I open electron and run my nightmare script in combination with Vo. Inside the script I go to a site, loop through a list of links and check if someone lives in Australia.
When I have an error, for example Timeout, the browser stops working.
Error Example ->
{ message: 'navigation error',
code: -7,
details: 'Navigation timed out after 30000 ms',
url: 'https://facebook.com/login' }
Here is my Code
var fs = require('fs');
var csv = require('fast-csv');
var vo = require('vo');
var Nightmare = require('nightmare');
var count = 0;
var urls = fs.readFileSync('uniqueIds.csv').toString().split("\n");
var arrayUrls = Object.keys(urls).map(function (key) {return urls[key]});
var bloqNumber = 0;
function *run(proxy, user, pass, urlsID) {
var nightmare = new Nightmare({
webPreferences: { partition: 'your-custom-partition'},
switches:{
'proxy-server': proxy,
'ignore-certificate-errors': true
}, show: true });
yield nightmare
.goto('https://facebook.com/login')
.wait(".inputtext._55r1.inputtext._1kbt.inputtext._1kbt")
.type('input[name="email"]', user)
.type('input[name="pass"]', pass)
.click('button[name=login]')
.wait(29000);
var range = urlsID * 2000;
var rangeStart = range - 2000;
var urlsarray = arrayUrls.slice(rangeStart, range);
for (var i = 0; i < urlsarray.length; i++) {
count++;
console.log(count + " -> " + proxy);
if (count > 150){
yield nightmare.end();
}
yield nightmare
.goto("https://www.facebook.com/profile.php?id=" + urlsarray[i] + "&sk=about§ion=living&pnref=about")
.wait(1000);
var seqCheck = yield nightmare.exists(".captcha_interstitial");
var bloqCheck = yield nightmare.exists(".mvl.ptm.uiInterstitial.uiInterstitialLarge.uiBoxWhite");
if (seqCheck == true) {
console.log("Seqcheck");
yield nightmare.wait(29000);
}
if (bloqCheck == true) {
console.log("Blocked for a week" + user + proxy);
bloqNumber++;
console.log(bloqNumber);
if (bloqNumber > 6) {
yield nightmare.end();
}
continue;
}
var location = yield nightmare.exists("._3pw9._2pi4._2ge8");
bloqNumber = 0;
console.log(location);
if (location == true) {
var getLocation = yield nightmare.evaluate(function() {
var jsonObject = new Array();
var links = document.getElementsByClassName('_3pw9 _2pi4 _2ge8');
var numProfiles = links.length;
for(var i = 0; i< numProfiles; i++){
var elem;
try {
elem = links[0].querySelector("._50f5._50f7 a").text;
} catch (err) {
var arrr = new Array('Hello', 'world');
return arrr;
}
jsonObject.push(elem);
}
return jsonObject;
});
var locationString = getLocation.join(" + ");
console.log(locationString + " -> " + urlsarray[i]);
if (locationString.indexOf("Australia") !== -1 ||
locationString.indexOf("Queensland") !== -1 ||
locationString.indexOf("New South Wales") !== -1 ||
locationString.indexOf("Victoria") !== -1 ||
locationString.indexOf("Northern Territory") !== -1 ||
locationString.indexOf("South Australia") !== -1||
locationString.indexOf("Tasmania") !== -1 ||
locationString.indexOf("Sydney") !== -1 ||
locationString.indexOf("Adelaide") !== -1 ||
locationString.indexOf("Cairns") !== -1 ||
locationString.indexOf("Perth") !== -1 ||
locationString.indexOf("Melbourne") !== -1 ||
locationString.indexOf("Brisbane") !== -1 ||
locationString.indexOf("Bundaberg") !== -1 ||
locationString.indexOf("Canberra") !== -1 ||
locationString.indexOf("Newcastle") !== -1 ||
locationString.indexOf("Western Australia") !== -1 ) {
console.log("Im in australia");
var stringToPrint = urlsarray[i] + ", " + locationString + "\n";
fs.appendFile('pages.csv', stringToPrint.replace(/(\r\n|\n|\r)/gm,"") + "\n", function (err) {
console.log("a new entry");
});
}
} else {
console.log("It was false");
}
}
yield nightmare.end();
}
fs.createReadStream('proxies.csv')
.pipe(csv())
.on('data', function (data) {
var proxy = data[0];
var user = data[1];
var pass = data[2];
var urlsID = data[3];
console.log(urlsID);
console.log(user);
console.log(pass);
vo(run(proxy, user, pass, urlsID)).then(out => console.log('out', out)).catch(error => console.log(error));
}).on('end', function (data) {
console.log('CSV reading finished.')
});
Desired Outcome:
I want every time i get some kind of error that my thread is closing.
Solved. Just append .catch like in the example below.
yield nightmare
.goto('https://facebook.com/login')
.wait(".inputtext._55r1.inputtext._1kbt.inputtext._1kbt")
.type('input[name="email"]', user)
.type('input[name="pass"]', pass)
.click('button[name=login]')
.wait(29000).catch(function(err){
console.dir(err);
nightmare.end();
});
I am developping an hybrid app (JQM 1.4 + Phonegap 3.6.3).
I have a function populateImagesUrlsLocalAndServer that checks if an image file exists on my server, but I can't use this function because it makes my app crash on Phonegap...
I can't find why.
Can you help me fix this issue so I can use this feature in my app again ?
Thank
function populateImagesUrlsLocalAndServer(str, baseUrl, type) {
if (connectionStatus == "online") {
if (UrlExists('./'+baseUrl+str)) { //local file
imagesUrls[str] = './'+baseUrl+str;
} else if (isPhoneGap && UrlExists('http://boardlineapp.com/app/'+baseUrl+str)) { //server file....we exclude this for desktop browser because of cross domain error
console.log('retrieving '+'http://boardlineapp.com/app/'+baseUrl+str+' on server')
imagesUrls[str] = 'http://boardlineapp.com/app/'+baseUrl+str;
} else {
imagesUrls[str] = './'+baseUrl+'default.png';
}
} else { //offline
if (UrlExists('./'+baseUrl+str)) { //local file
imagesUrls[str] = './'+baseUrl+str;
} else {
imagesUrls[str] = './'+baseUrl+'default.png';
}
}
imagesUrls[str+'type'] = type;
}
instead, for now I am using :
function populateImagesUrls(str, baseUrl, type) {
if ( str == 'byrne-ow-fender.png'
|| str == 'ci-tacogrinder.png'
|| str == 'noamizuno.png'
|| str == 'brendanmargieson.png'
|| str == 'kaihing.png'
|| str == 'dustinhollick.png'
|| str == 'dhd-thetwin.png'
) {
//console.log(str);
//console.log(baseUrl);
imagesUrls[str] = './'+baseUrl+'default.png';
} else {
imagesUrls[str] = './'+baseUrl+str;
}
imagesUrls[str+'type'] = type;
}
the function that calls it is the following:
function checkIfImagesExistAllAtOnce() {
var prodataTemp = [];
prodataTemp = prodata.slice();
prodataTemp.shift();
prodataTemp.sort(sort_by('brand', 'name', 'model'));
var strBrandDone;
var strNameDone;
var strModelDone;
for (i = 1; i < prodataTemp.length; ++i) {
//check brand
var str = prodataTemp[i]['brand'].replace(/\s+/g, '').toLowerCase();
str = str+'.png';
if (str != strBrandDone) {
var baseUrl = "images/brands/";
strBrandDone = str;
var type = "brand";
populateImagesUrls(str, baseUrl, type);
//populateImagesUrlsLocalAndServer(str, baseUrl, type);
}
//check pro image
var str = prodataTemp[i]['name'].replace(/\s+/g, '').toLowerCase();
str = str+'.png';
if (str != strNameDone) {
var baseUrl = "images/pros/";
strNameDone = str;
var type = "pro";
populateImagesUrls(str, baseUrl, type);
//populateImagesUrlsLocalAndServer(str, baseUrl, type);
}
//check board image
var str = prodataTemp[i]['imageName'];
if (str != strModelDone) {
var baseUrl = "images/boards/";
strModelDone = str;
var type = "board";
populateImagesUrls(str, baseUrl, type);
//populateImagesUrlsLocalAndServer(str, baseUrl, type);
}
}
prodataTemp = null;
}
I have to ask the question again today.
I am in the course of processing a code to connect to one to one to the code allowing for a group conversation. Without beating around the bush, I have this code:
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
};
};
While the conversation between two users working well, then when adding another member, it no longer connects to the other two peers, although clearly the logs I see that attaches to the same room.
In the console, no errors.
Does anyone would be kind to help?
#edit
I'm adding server code too if needed:
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);
});
});
Finally solved the problem. The general rule of writing conferences, where all peers are connected to is this: each new incoming plays the role of answerer, and after creating a connection with all offers who send him an offer, begins to act as offerer (except the first peer, which is always the offer). #Mert Koksal, thank you for your interest thread.