start experimenting with a fallback layer

This commit is contained in:
Calvin Montgomery 2013-06-03 23:56:06 -04:00
parent 70f2065a36
commit 9eafc53c91
6 changed files with 226 additions and 0 deletions

View File

@ -19,6 +19,7 @@ var Logger = require("./logger.js");
var InfoGetter = require("./get-info.js");
var Server = require("./server.js");
var io = Server.io;
var NWS = require("./notwebsocket");
var Rank = require("./rank.js");
var Auth = require("./auth.js");
var ChatCommand = require("./chatcommand.js");
@ -760,6 +761,7 @@ Channel.prototype.sendRecentChat = function(user) {
Channel.prototype.sendAll = function(message, data) {
io.sockets.in(this.name).emit(message, data);
NWS.inRoom(this.name).emit(message, data);
}
Channel.prototype.broadcastPlaylistMeta = function() {

118
notwebsocket.js Normal file
View File

@ -0,0 +1,118 @@
const chars = "abcdefghijklmnopqsrtuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
"0123456789";
var NotWebsocket = function() {
this.hash = "";
for(var i = 0; i < 30; i++) {
this.hash += chars[parseInt(Math.random() * (chars.length - 1))];
}
this.pktqueue = [];
this.handlers = {};
this.room = "";
}
NotWebsocket.prototype.emit = function(msg, data) {
//hack because something fishy is going on
if(typeof msg === "object") {
data = msg["1"];
msg = msg["0"];
}
var pkt = [msg, data];
this.pktqueue.push(pkt);
}
NotWebsocket.prototype.poll = function() {
var q = this.pktqueue;
this.pktqueue = [];
return q;
}
NotWebsocket.prototype.on = function(msg, callback) {
if(!(msg in this.handlers))
this.handlers[msg] = [];
this.handlers[msg].push(callback);
}
NotWebsocket.prototype.recv = function(urlstr) {
var msg, data;
try {
var js = JSON.parse(urlstr);
msg = js[0];
data = js[1];
}
catch(e) {
console.log("Failed to parse NWS string");
}
if(!msg)
return;
if(!(msg in this.handlers))
return;
for(var i = 0; i < this.handlers[msg].length; i++) {
this.handlers[msg][i](data);
}
}
NotWebsocket.prototype.join = function(rm) {
this.room = rm;
}
NotWebsocket.prototype.disconnect = function() {
}
function sendJSON(res, obj) {
var response = JSON.stringify(obj, null, 4);
if(res.callback) {
response = res.callback + "(" + response + ")";
}
var len = unescape(encodeURIComponent(response)).length;
res.setHeader("Content-Type", "application/json");
res.setHeader("Content-Length", len);
res.end(response);
}
var clients = {};
function newConnection(req, res) {
var nws = new NotWebsocket();
clients[nws.hash] = nws;
sendJSON(res, nws.hash);
return nws;
}
exports.newConnection = newConnection;
function msgReceived(req, res) {
var h = req.params.hash;
if(h in clients) {
if(req.params.str == "poll") {
sendJSON(res, clients[h].poll());
}
else {
clients[h].recv(unescape(req.params.str));
sendJSON(res, "");
}
}
}
exports.msgReceived = msgReceived;
function inRoom(rm) {
var cl = [];
for(var h in clients) {
if(clients[h].room == rm) {
cl.push(clients[h]);
}
}
return {
emit: function() {
for(var i = 0; i < this.cl.length; i++) {
this.cl[i].emit(arguments);
}
},
cl: cl
};
}
exports.inRoom = inRoom;

View File

@ -18,6 +18,7 @@ Logger.syslog.log("Starting CyTube v" + VERSION);
var Config = require("./config.js");
var express = require("express");
var API = require("./api.js");
var NWS = require("./notwebsocket");
var app = express();
app.get("/r/:channel(*)", function(req, res, next) {
@ -34,6 +35,53 @@ app.get("/api/:apireq(*)", function(req, res, next) {
API.handle(req.url.substring(5), req, res);
});
function getClientIP(req) {
var ip;
var forward = req.header("x-forwarded-for");
if(forward) {
ip = forward.split(",")[0];
}
if(!ip) {
ip = req.connection.remoteAddress;
}
return ip;
}
app.get("/nws/connect", function(req, res, next) {
var socket = NWS.newConnection(req, res);
var ip = getClientIP(req);
if(Database.checkGlobalBan(ip)) {
Logger.syslog.log("Disconnecting " + ip + " - bant");
socket.emit("kick", {
reason: "You're globally banned!"
});
socket.disconnect(true);
return;
}
socket.on("disconnect", function() {
exports.clients[ip]--;
});
if(!(ip in exports.clients)) {
exports.clients[ip] = 1;
}
else {
exports.clients[ip]++;
}
if(exports.clients[ip] > Config.MAX_PER_IP) {
socket.emit("kick", {
reason: "Too many connections from your IP address"
});
socket.disconnect(true);
return;
}
var user = new User(socket, ip);
Logger.syslog.log("Accepted connection from /" + user.ip);
});
app.get("/nws/:hash/:str", function(req, res, next) {
NWS.msgReceived(req, res);
});
app.get("/:thing(*)", function(req, res, next) {
res.sendfile(__dirname + "/www/" + req.params.thing);
});

View File

@ -835,6 +835,7 @@ Callbacks = {
}
}
/*
$.getScript(IO_URL+"/socket.io/socket.io.js", function() {
try {
socket = io.connect(IO_URL);
@ -846,3 +847,9 @@ $.getScript(IO_URL+"/socket.io/socket.io.js", function() {
Callbacks.disconnect();
}
});
*/
socket = new NotWebsocket();
for(var key in Callbacks) {
socket.on(key, Callbacks[key]);
}

View File

@ -0,0 +1,50 @@
var NotWebsocket = function() {
this.connected = false;
$.getJSON(WEB_URL + "/nws/connect", function(data) {
this.hash = data;
this.connected = true;
this.recv(["connect", undefined]);
this.pollint = setInterval(function() {
this.poll();
}.bind(this), 100);
}.bind(this));
this.handlers = {};
}
NotWebsocket.prototype.emit = function(msg, data) {
if(!this.connected) {
setTimeout(function() {
this.emit(msg, data);
}.bind(this), 100);
}
var pkt = [msg, data];
var str = escape(JSON.stringify(pkt));
$.getJSON(WEB_URL+"/nws/"+this.hash+"/"+str, function(){});
}
NotWebsocket.prototype.on = function(msg, callback) {
if(!(msg in this.handlers))
this.handlers[msg] = [];
this.handlers[msg].push(callback);
}
NotWebsocket.prototype.poll = function() {
if(!this.connected)
return;
$.getJSON(WEB_URL+"/nws/"+this.hash+"/poll", function(data) {
for(var i = 0; i < data.length; i++) {
console.log("DBG", data[i]);
this.recv(data[i]);
}
}.bind(this));
}
NotWebsocket.prototype.recv = function(pkt) {
var msg = pkt[0], data = pkt[1];
if(!(msg in this.handlers))
return;
for(var i = 0; i < this.handlers[msg].length; i++) {
this.handlers[msg][i](data);
}
}

View File

@ -313,6 +313,7 @@
<script src="./assets/js/media.js"></script>
<script src="./assets/js/functions.js"></script>
<script src="./assets/js/client.js"></script>
<script src="./assets/js/notwebsocket.js"></script>
<script src="./assets/js/callbacks.js"></script>
<!-- APIs -->
<script src="http://api.dmcdn.net/all.js"></script>