Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Removed dependency to irc-js.

Redesign code to make nodester server a proxy for a webclient irc client.
Some cleanup.

Signed-off-by: Paul Maxan <pmaxan@yahoo.com>
  • Loading branch information...
commit d7105c18f6533247c0d445bb08b878dcdff3b912 1 parent 92c2cbf
@microp11 microp11 authored
View
412 irc.js
@@ -1,29 +1,44 @@
/***************************************\
- IRC#nodester client
+ IRC#nodester client/proxy
\***************************************/
/*
* @name : irc.js
* @mainteiner : Alejandro Morales <vamg008@gmail.com>
* @licence : GNU Affero
- * @updated : 17-03-2012
+ * @updated : 15-04-2012
* @repo : http://github.com/nodester/irc
- * @version : 2.0.0
+ * @version : 2.0.1
*
* @note : Currently there is no implementation for IRC commands.
- * : This choice is by design.
+ * : This choice is by design.
+ * :
+ * : Nodester irc app acts like a proxy for a real irc server.
+ * :
+ * : This implementation can be further simplified by replacing
+ * : express with a static http file server
*/
-var http = require('http')
- , fs = require('fs')
- , io = require('socket.io')
- , express = require('express')
- , ircjs = require('irc-js')
- , cfg = { channel:'#nodester' }
- , app = express.createServer()
- , io = require('socket.io').listen(app);
+var express = require('express'),
+ sio = require('socket.io'),
+ Proxy = require('./tcp-proxy');
-//when the app started
+var app = module.exports = express.createServer();
+
+var allowCORS = function (req, res, next) {
+ res.header("Access-Control-Allow-Origin", "*");
+ res.header("Access-Control-Allow-Headers", "X-Requested-With");
+ res.header("Strict-Transport-Security", "max-age=31556926; includeSubDomains");
+ res.header("X-Powered-By", "nodeJS");
+ next();
+};
+
+app.configure(function (){
+ app.use(express.static(__dirname + '/public'));
+ app.use(allowCORS);
+});
+
+//when the app starts
var startTime = (new Date()).getTime(),
statTime = startTime;
@@ -32,12 +47,9 @@ var currMem = process.memoryUsage().rss,
minMem = currMem,
maxMem = currMem;
-var webUsers = [],
- bWebUsersDirty = false; //flag to indicate if the webUsers changed
-
//every 15 seconds poll for the memory
var tmr = setInterval(function () {
- statTime = new Date().toTimeString().substr(0,9);
+ statTime = new Date().toTimeString().substr(0, 9);
currMem = process.memoryUsage().rss;
if (currMem < minMem) {
minMem = currMem;
@@ -49,366 +61,18 @@ var tmr = setInterval(function () {
}, 15*1000);
process.on('uncaughtException', function (err) {
- console.log('Uncaught error: ' + err.stack);
+ console.log('Uncaught error: ' + err.stack);
});
-var allowCORS = function(req,res,next){
- res.header("Access-Control-Allow-Origin", "*");
- res.header("Access-Control-Allow-Headers", "X-Requested-With");
- res.header("Strict-Transport-Security", "max-age=31556926; includeSubDomains");
- res.header("X-Powered-By","nodeJS");
- next();
-};
-
-app.configure(function(){
- app.use(express.static(__dirname + '/public'));
- app.use(allowCORS);
-});
-
-app.get('/', function(req, res, next){
- res.render('./public/index.html');
+app.get('/', function (req, res, next) {
+ res.render('./public/index.html');
});
-app.listen(process.env.C9_PORT || process.env['app_port'] || 80);
-
-console.log('IRC#nodester is running on %d',app.address().port)
-
-/*
- * Sockets stuff
-*/
-io.set('log level', 1); //reduce debug messages
-io.sockets.on('connection', function (client) {
- var socket = client,
- irc = null,
- nickname = null;
- client.on('message', function(data) {
- var obj = JSON.parse(data);
- if (obj.hasOwnProperty('nickname')) {
- if (irc === null) {
- nickname = obj.nickname;
- irc = new ircjs({
- server: 'irc.freenode.net',
- port: 6667,
- nick: nickname,
- user: {
- username: nickname,
- hostname: 'irc.nodester.com',
- servername: 'irc.freenode.net',
- realname: nickname + ' via http://irc.nodester.com/'
- },
- log: false
- });
-
- console.log(irc)
-
- /*
- * Initiating a connection to the irc server
- * When the connection with the irc server is established and ready,
- * we issue a call to join.
- */
- irc.connect(function () {
- irc.join(cfg.channel);
- });
-
- /*
- * Handler for private messages
- * There is no private messaging using the web client.
- * in case o private message is received, a message is sent back to the caller
- * explaining that there is no privacy!
- */
- irc.addListener('privmsg', function (message) {
- if (message.params[0] == cfg.channel) {
- client.send(JSON.stringify({
- messagetype: "message",
- from: message.person.nick,
- channel: (message.params[0]),
- message: (message.params[1])
- }));
- } else {
- irc.privmsg(message.person.nick,
- "Automatic: I am using a web client. I can only talk on channel #nodester.");
- }
- });
-
- /*
- * Handler for join
- */
- irc.addListener('join', function (message) {
- client.send(JSON.stringify({
- messagetype: "join",
- from: (message.person.nick),
- channel: (message.params[0])
- }));
- });
-
- /*
- * Handler for the topic, 332
- */
- irc.addListener('332', function (raw) {
- client.send(JSON.stringify({
- messagetype: "topic",
- //nick
- from: (raw.params[0]),
- //channel
- channel: (raw.params[1]),
- //topic
- message: (raw.params[2])
- }));
- });
-
- /*
- * Handler for names.
- * There can be multiple such calls as the names are retrieved, 353
- */
- irc.addListener('353', function (raw) {
- client.send(JSON.stringify({
- messagetype: "names",
- //nick
- from: (raw.params[0]),
- //channel
- channel: (raw.params[2]),
- message: "",
- //users as a space delimited string
- users: (raw.params[3].split(" "))
- }));
- });
-
- /*
- * Handler for end of names list, 366
- */
- irc.addListener('366', function (raw) {
- client.send(JSON.stringify({
- messagetype: "endnames",
- //nick
- from: (raw.params[0]),
- //channel
- channel: (raw.params[1]),
- }));
- });
-
- /*
- * Handler for quitting
- * This event will not be triggered after an irc.quit() call
- */
- irc.addListener('quit', function (message) {
- client.send(JSON.stringify({
- messagetype: "quit",
- from: (message.person.nick),
- channel: (message.params[0])
- }));
- });
-
- /*
- * Handler for parting the channel, while remaining connected to the irc server
- */
- irc.addListener('part', function (message) {
- client.send(JSON.stringify({
- messagetype: "part",
- from: (message.person.nick),
- channel: (message.params[0])
- }));
- });
-
- /*
- * Handler for server reporting nick change
- */
- irc.addListener('nick', function (message) {
- var prevNick = message.person.nick,
- newNick = message.params[0];
- /*
- * if ever this client will send commands, the code below will be needed
- *
- for (var i = 0; i < webUsers.length; i++) {
- if (webUsers[i] == prevNick) {
- webUsers[i] = newNick;
- bWebUsersDirty = true;
- break;
- };
- };
- */
- client.send(JSON.stringify({
- messagetype: "nick",
- from: prevNick,
- channel: "",
- message: newNick
- }));
- });
-
- /*
- * Handler for a motd line, 372
- * There are multiple calls as such until the entire motd is received
- * Note: not all servers emit a motd!
- */
- irc.addListener('372', function (raw) {
- client.send(JSON.stringify({
- messagetype: "motd",
- //server
- from: (raw.server),
- //channel
- channel: "",
- //topic
- message: (raw.params[1])
- }));
- });
-
- /*
- * Handler for the end of motd, 376
- */
- irc.addListener('376', function (raw) {
- client.send(JSON.stringify({
- messagetype: "endmotd",
- //server
- from: (raw.server)
- }));
- });
-
- /*
- * Handler for the welcome message
- * This indicates that the irc server accepted our request, and while there
- * are further possible notifications, for us this is a sign that we can
- * close the login screen and open the main window.
- */
- irc.addListener('001', function (raw) {
- webUsers.push(irc.options.nick);
- bWebUsersDirty = true; //for self
- client.send(JSON.stringify({
- messagetype: "001",
- //server
- from: (raw.server),
- //channel
- channel: "",
- //topic
- message: (raw.params[1])
- }));
- });
-
- /*
- * Handler for notices
- */
- irc.addListener('notice', function (message) {
- if (message.person !== undefined) {
- //notice for content
- client.send(JSON.stringify({
- messagetype: "notice-msg",
- from: (message.person.nick),
- channel: "",
- message: (message.params[1])
- }));
- } else {
- //notice at login
- client.send(JSON.stringify({
- messagetype: "notice",
- from: (message.params[0]),
- channel: "",
- message: (message.params[1])
- }));
- }
- });
-
- /*
- * Handler for irc error 433: nick already in use.
- * We use this particular handler for the login screen
- */
- irc.addListener('433', function (message) {
- client.send(JSON.stringify({
- messagetype: "433",
- //rejected nick
- from: (message.params[1]),
- //the irc server as channel
- channel: message.server,
- //the rejection message, usually "Nickname is already in use."
- message: (message.params[2])
- }));
- });
-
- /*
- * Handler for all irc server errors
- * This has nothing to do with the eventual irc-js implementation errors
- * Handles all error messages but 433 handled above
- */
- for (var err = 400; err < 600; err++) {
- if (err != 433) {
- irc.addListener(err, function (raw) {
- client.send(JSON.stringify({
- messagetype: "notice-err",
- from: "",
- channel: "",
- message: raw.raw
- }));
- }); //addListener
- }; //if
- }; //for
-
- /*
- * Handler for our own client
- * e.g., timeout
- */
- irc.addListener('error', function () {
- client.send(JSON.stringify({
- messagetype: "error"
- }));
- });
- } else {
- // Maybe handle updating of nicks one day :)
- }
- } else if (obj.hasOwnProperty('messagetype')) {
- /*
- * Handler for a web client request to send a message to the irc server
- */
- switch (obj.messagetype) {
- case "message":
- irc.privmsg(cfg.channel, (obj.message));
- break;
- default:
- console.log(data);
- break;
- }
- } else if (obj.hasOwnProperty('statistics')) {
- /*
- * Handler for a web client request for statistics
- * The statistics are gathered every 15 seconds. There will be a lag
- * of less than 15 seconds since the last statistics "crop"
- */
- client.send(JSON.stringify({
- messagetype: "statistics",
- st: startTime,
- min: minMem,
- max: maxMem,
- current: currMem,
- wud: bWebUsersDirty
- }));
- } else if (obj.hasOwnProperty('webusers')) {
- /*
- * Handler for a webclient request for webusers
- * These are the users that connect to the irc server through
- * our irc client. There is no mode attributes attached to these users.
- */
- bWebUsersDirty = false;
- client.send(JSON.stringify({
- messagetype: "webusers",
- wu: webUsers
- }));
- };
- });
-
- /*
- * Handler for socket disconnect
- * This event indicates that the connection in between the web client and our
- * irc client (server for the socket communication to the web client) has been
- * lost. Currently we close the irc connection for that particular web client.
- */
- client.on('disconnect', function() {
- if (irc){
- for (var i = 0; i < webUsers.length; i++) {
- if (webUsers[i] == irc.options.nick) {
- webUsers.splice(i, 1);
- bWebUsersDirty = true;
- break;
- }
- }
- irc.quit();
- irc = null;
- }
- });
+app.listen(process.env.C9_PORT || process.env['app_port'] || 16932);
+console.log("IRC#nodester is running on port %d in %s mode", app.address().port, app.settings.env);
+var io = sio.listen(app);
+io.set('log level', 0);
+io.sockets.on('connection', function (socket) {
+ var proxy = new Proxy(socket);
});
View
1  package.json
@@ -5,7 +5,6 @@
, "author":"Alejandro Morales"
, "dependencies":{
"socket.io":"0.9.x"
- , "irc-js":"*"
, "express":"2.5.x"
}
}
View
20 public/index.html
@@ -3,10 +3,9 @@
<head>
<meta charset="utf-8">
<title>Nodester IRC Channel</title>
- <link href='http://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
- <link rel="stylesheet" href="css/irc.css" >
+ <link href="http://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet" type="text/css">
+ <link href="css/irc.css" rel="stylesheet">
</head>
-<body onload="">
<div id="main-wrapper">
<div id="wrapper" class="rocket box">
@@ -16,11 +15,11 @@
<div class="rocket">
<h2>IRC #nodester channel</h2>
<br />
- <p class="off" style="color:red;" id="wrong"> You need to specify a valid nickname</p>
+ <p class="off" style="color:red;" id="wrong">You need to specify a valid nickname</p>
<p class="off" id="login-msg"></p>
<form id="join-form">
<input type="text" id="nick" class="btn" placeholder="username">
- <button href="#" class="btn btn-info" id="join">Join</button>
+ <button type="submit" href="#" class="btn btn-info" id="join">Join</button>
</form>
</div>
<table id="login-status">
@@ -50,7 +49,7 @@
</div>
<div id="chat_bar">
<form id="chat-form">
- <input type="text" id="text_input" class="btn" placeholder="send a message" size="80">
+ <input type="text" id="text_input" class="btn" placeholder="send a message" size="80" />
<button type="submit" class="btn btn-info clic" id="sendMessage">Send</button>
</form>
</div>
@@ -66,11 +65,14 @@
<div id="js">
<script src="//code.jquery.com/jquery.js" type="text/javascript"></script>
+ <script src="/js/tcp-client.js" type="text/javascript"></script>
+ <script src="/js/irc-client.js" type="text/javascript"></script>
+ <script src="/js/app.js" type="text/javascript"></script>
+ <script src="/socket.io/socket.io.js"></script>
+
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.1/underscore-min.js" type="text/javascript"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.string/1.1.6/underscore.string.min.js" type="text/javascript"></script>
- <script type="text/javascript" src="/js/plugins.min.js"></script>
- <script src="/socket.io/socket.io.js"></script>
- <script src="/js/app.js" type="text/javascript"></script>
+ <script src="/js/plugins.min.js" type="text/javascript"></script>
<script src="/js/date.utils.js" type="text/javascript"></script>
<script src="/js/utils.js" type="text/javascript"></script>
</div>
View
82 public/js/app.js
@@ -1,6 +1,6 @@
$(document).ready(function() {
- var sock = null,
- rv = null,
+ var ircClient = new IRCClient("irc.freenode.net", 6667);
+ var rv = null,
nickname = null,
nicks = [], //could be an object if later we decide to add the nick attributes (+,... @)
webNicks = [], //web irc users
@@ -119,14 +119,14 @@ $(document).ready(function() {
loginWrong.addClass('off');
loginMsg.removeClass('off');
chatBody.text("");
- if (sock !== null && sock.socket.connected === false) {
- sock.socket.reconnect();
- } else {
- sock = io.connect('http://' + window.location.host, {'reconnect': false});
- sock.on('message', handleMessage);
- sock.on('disconnect', handleDisconnect);
- sock.on('connect', handleConnect);
- };
+
+ //initiate connect to the irc server
+ ircClient.disconnect();
+ ircClient.clearAll();
+ ircClient.on("connected", handleOnConnected);
+ ircClient.on("disconnected", handleOnDisconnected);
+ ircClient.on("data", handleOnData);
+ ircClient.connect();
} else {
loginWrong.removeClass('off');
}
@@ -286,24 +286,24 @@ $(document).ready(function() {
nickUl.html(content);
};
- var handleMessage = function (data) {
+ var handleOnData = function (data) {
var obj = JSON.parse(data);
if (obj && obj.messagetype) {
var isSelf = (obj.from == nickname) ? true : false;
switch (obj.messagetype) {
case "433": //nick already in use
window.spinner.stop();
- sock.disconnect();
+ ircClient.disconnect();
loginMsg.addClass('off');
loginWrong.text("");
loginWrong.removeClass('off');
loginWrong.text(obj.message);
joinBtn.removeAttr("disabled");
return;
- //notice at login
+ //notice at login and...
case "notice":
case "notice-err":
- //notice for content
+ //... notice for content
case "notice-msg":
if (c.getIrcNoticesEnabled() == true) {
appendMessage(obj.from, obj.message, false);
@@ -316,7 +316,7 @@ $(document).ready(function() {
break;
case "error": //nick already in use
window.spinner.stop();
- sock.disconnect();
+ ircClient.disconnect();
loginMsg.addClass('off');
loginWrong.text("");
loginWrong.removeClass('off');
@@ -325,7 +325,7 @@ $(document).ready(function() {
return;
case "message":
appendMessage(obj.from, obj.message, false);
- requestStatistics();
+ //ircClient.requestStatistics();
break;
case "topic":
appendMessage("Topic", obj.message, false);
@@ -362,6 +362,8 @@ $(document).ready(function() {
logBox.slideToggle();
nickLabel.text(nickname);
joinBtn.removeAttr("disabled");
+ //initiate join to irc channel
+//TODO ircClient.joinChannel("#nodester");
break;
case "join":
appendEvent(obj.from, obj.messagetype, isSelf);
@@ -370,7 +372,7 @@ $(document).ready(function() {
nicks.sort(cisort);
nicksToList();
}
- requestStatistics();
+ //ircClient.requestStatistics();
break;
case "quit":
case "part":
@@ -382,7 +384,7 @@ $(document).ready(function() {
}
}
nicksToList();
- requestStatistics();
+ //ircClient.requestStatistics();
break;
case "nick":
appendEvent(obj.from, obj.messagetype, isSelf, obj.message);
@@ -394,13 +396,13 @@ $(document).ready(function() {
}
nicks.sort(cisort);
nicksToList();
- //requestStatistics(); this call will be needed if the web client will also send commends
+ //ircClient.requestStatistics(); this call will be needed if the web client will also send commands
break;
case "statistics":
c.updateStats(obj);
if (obj.wud == true) {
//the webusers list has been changed, we initiate retrieval
- requestWebUsers();
+ ircClient.requestWebUsers();
}
var header_class = (c.getStatsEnabled() == true) ? 'header-stats' : 'header-stats off';
nickLabel.html('<span class="'+header_class+'">Server up for ' + c.getServerTime()
@@ -419,14 +421,14 @@ $(document).ready(function() {
}
};
- var handleConnect = function () {
+ var handleOnConnected = function () {
loginMsg.text("");
loginStatus.html("");
var nick = window.nick = getNickname(nickText.val());
loginMsg.text("Joining as " + nick + "...");
joinBtn.prop("disabled", "disabled");
c.setIrcNoticesEnabled(false);
- sock.send(JSON.stringify({ nickname: nick }));
+ ircClient.registerNick(nick);
//start spinner
window.target = document.getElementById('join-form');
window.spinner = new Spinner(c.getOpts()).spin(window.target);
@@ -436,7 +438,7 @@ $(document).ready(function() {
* set a time delay for disconnect
* in case we exit the form we do not want the user to see it
*/
- var handleDisconnect = function () {
+ var handleOnDisconnected = function () {
setTimeout( function () {
appendEvent("*", "disconnected", false);
nicks = [];
@@ -446,26 +448,10 @@ $(document).ready(function() {
var sendMessage = function () {
appendMessage(nickname, textInput.val(), true);
- sock.send(JSON.stringify({
- messagetype: "message",
- message: textInput.val()
- }));
+ ircClient.send(textInput.val());
textInput.val('');
};
- /*
- * requesting statistics is user action triggered
- * in case it is proven to be to resource intensive
- * another solution can be sought, e.g., on a timer
- */
- var requestStatistics = function () {
- sock.send(JSON.stringify({ statistics: ""}))
- };
-
- var requestWebUsers = function () {
- sock.send(JSON.stringify({ webusers: ""}))
- };
-
chatForm.on('submit', function (e) {
e.preventDefault();
if (textInput.val() !== '') {
@@ -477,22 +463,6 @@ $(document).ready(function() {
return false;
});
-/* var ocolors = {
- 'bold' : ['\033[1m', '\033[22m'],
- 'italic' : ['\033[3m', '\033[23m'],
- 'underline' : ['\033[4m', '\033[24m'],
- 'inverse' : ['\033[7m', '\033[27m'],
- 'white' : ['\033[37m', '\033[39m'],
- 'grey' : ['\033[90m', '\033[39m'],
- 'black' : ['\033[30m', '\033[39m'],
- 'blue' : ['\033[34m', '\033[39m'],
- 'cyan' : ['\033[36m', '\033[39m'],
- 'green' : ['\033[32m', '\033[39m'],
- 'magenta' : ['\033[35m', '\033[39m'],
- 'red' : ['\033[31m', '\033[39m'],
- 'yellow' : ['\033[33m', '\033[39m']
- };
-*/
var colors = {
'p' :['<p>','</p>'],
'[1m' :['<strong>','</strong>'],
View
412 public/js/irc-client.js
@@ -0,0 +1,412 @@
+/*
+ * The irc parser function below is taken from:
+ * https://github.com/martynsmith/node-irc
+ */
+
+var IRCClient = function (host, port) {
+ this.host = host;
+ this.port = port;
+ this.client = new Client(host, port);
+
+ //callbacks for the IRCClient caller
+ this.callbacks = {};
+
+ //used for internal data processing
+ this.buffer = '';
+
+ return this;
+}
+
+IRCClient.prototype.connect = function () {
+ var that = this;
+ this.client.on("connected", function () {
+ that.emit("connected");
+ });
+
+ this.client.on("closed", function () {
+ that.emit("disconnected");
+ });
+
+ this.client.on("data", function (chunk) {
+ that.buffer += chunk.data;
+ var lines = that.buffer.split("\r\n");
+ that.buffer = lines.pop();
+ lines.forEach(function (line) {
+ var message = parseMessage(line, true);
+ try {
+ emulateMessage(that, message);
+ //that.emit("data", message);
+ } catch ( err ) {
+ that.emit("error", err.message);
+ }
+ });
+ });
+
+ this.client.connect();
+}
+
+IRCClient.prototype.registerNick = function (nick) {
+ this.client.send("NICK " + nick + "\r\n");
+ this.client.send("USER " + nick + " irc.nodester.com irc.freenode.net :" + nick + " via http://irc.nodester.com\r\n");
+}
+
+IRCClient.prototype.joinChannel = function (channel) {
+ this.client.send("JOIN " + channel + "\r\n");
+}
+
+IRCClient.prototype.disconnect = function () {
+ this.client.disconnect();
+}
+
+IRCClient.prototype.send = function (message) {
+ //format message if needed
+ this.client.send(message);
+}
+
+IRCClient.prototype.requestStatistics = function () {
+ this.client.send("requestStatistics");
+}
+
+IRCClient.prototype.requestWebUsers = function () {
+ this.client.send("requestWebUsers");
+}
+
+IRCClient.prototype.clearAll = function () {
+ this.callbacks = {};
+}
+
+IRCClient.prototype.emit = function (event, param) {
+ if (typeof this.callbacks[event] === "function")
+ this.callbacks[event].call(this, param);
+}
+
+IRCClient.prototype.on = function (event, callback) {
+ if (typeof callback === "function")
+ this.callbacks[event] = callback;
+ return this;
+}
+
+/*
+ * The irc parser is taken from:
+ * https://github.com/martynsmith/node-irc
+ *
+ * parseMessage(line, stripColors)
+ *
+ * takes a raw "line" from the IRC server and turns it into an object with
+ * useful keys
+ */
+var parseMessage = function (line, stripColors) {
+ var message = {};
+ var match;
+
+ if (stripColors) {
+ line = line.replace(/[\x02\x1f\x16\x0f]|\x03\d{0,2}(?:,\d{0,2})?/g, "");
+ }
+
+ // Parse prefix
+ if ( match = line.match(/^:([^ ]+) +/) ) {
+ message.prefix = match[1];
+ line = line.replace(/^:[^ ]+ +/, '');
+ if ( match = message.prefix.match(/^([_a-zA-Z0-9\[\]\\`^{}|-]*)(!([^@]+)@(.*))?$/) ) {
+ message.nick = match[1];
+ message.user = match[3];
+ message.host = match[4];
+ }
+ else {
+ message.server = message.prefix;
+ }
+ }
+
+ // Parse command
+ match = line.match(/^([^ ]+) +/);
+ message.command = match[1];
+ message.rawCommand = match[1];
+ message.commandType = 'normal';
+ line = line.replace(/^[^ ]+ +/, '');
+ message.args = [];
+ var middle, trailing;
+
+ // Parse parameters
+ if (line.indexOf(':') != -1) {
+ var index = line.indexOf(':');
+ middle = line.substr(0, index).replace(/ +$/, "");
+ trailing = line.substr(index+1);
+ }
+ else {
+ middle = line;
+ }
+
+ if (middle.length)
+ message.args = middle.split(/ +/);
+
+ if (typeof(trailing) != 'undefined' && trailing.length)
+ message.args.push(trailing);
+
+ return message;
+};
+
+/*
+ * this is transitional to former irc.nodester.com implementation
+ * and some irc specific messaging
+ *
+ * the message param has the following fields:
+ * .server
+ * .nick
+ * .user
+ * .host
+ * .command
+ * .rawCommand
+ * .commandType
+ * .args as array
+ *
+ * the output data complies with the former irc.nodester.com JSON format:
+ * .messagetype
+ * .from
+ * .channel
+ * .message
+ * .users
+ */
+var emulateMessage = function (that, message) {
+ switch (message.command) {
+
+ /*
+ * Handler for notices
+ */
+ case "NOTICE":
+ if (message.nick !== undefined) {
+ //notice for content
+ that.emit("data", JSON.stringify({
+ messagetype: "notice-msg",
+ from: (message.nick),
+ channel: "",
+ message: (message.args[1]),
+ users: ""
+ }));
+ } else {
+ //notice at login
+ that.emit("data", JSON.stringify({
+ messagetype: "notice",
+ from: (message.args[0]),
+ channel: "",
+ message: (message.args[1]),
+ users: ""
+ }));
+ }
+ break;
+
+ /*
+ * Handler for the welcome message
+ * This indicates that the irc server accepted our request, and while there
+ * are further possible notifications, for us this is a sign that we can
+ * close the login screen and open the main window.
+ */
+ case "001":
+ //webUsers.push(irc.options.nick);
+ //bWebUsersDirty = true; //for self
+ that.emit("data", JSON.stringify({
+ messagetype: "001",
+ from: (message.args[0]),
+ channel: "",
+ message: (message.args[1]),
+ users: ""
+ }));
+ break;
+
+ /*
+ * Handler for a motd line, 372, max 80 chars
+ * There are multiple calls as such until the entire motd is received
+ * Note: not all servers emit a motd!
+ */
+ case "372":
+ that.emit("data", JSON.stringify({
+ messagetype: "motd",
+ from: (message.server),
+ channel: "",
+ message: (message.args[1]),
+ users: ""
+ }));
+ break
+
+ /*
+ * Handler for the end of motd, 376
+ */
+ case "376":
+ that.emit("data", JSON.stringify({
+ messagetype: "endmotd",
+ //server
+ from: (message.server)
+ }));
+ break;
+
+ default:
+ break;
+ }
+};
+
+// /*
+// * Handler for private messages
+// * There is no private messaging using the web client.
+// * in case o private message is received, a message is sent back to the caller
+// * explaining that there is no privacy!
+// */
+// irc.addListener('privmsg', function (message) {
+// if (message.params[0] == cfg.channel) {
+// client.send(JSON.stringify({
+// messagetype: "message",
+// from: message.person.nick,
+// channel: (message.params[0]),
+// message: (message.params[1])
+// }));
+// } else {
+// irc.privmsg(message.person.nick,
+// "Automatic: I am using a web client. I can only talk on channel #nodester.");
+// }
+// });
+//
+// /*
+// * Handler for join
+// */
+// irc.addListener('join', function (message) {
+// client.send(JSON.stringify({
+// messagetype: "join",
+// from: (message.person.nick),
+// channel: (message.params[0])
+// }));
+// });
+//
+// /*
+// * Handler for the topic, 332
+// */
+// irc.addListener('332', function (raw) {
+// client.send(JSON.stringify({
+// messagetype: "topic",
+// //nick
+// from: (raw.params[0]),
+// //channel
+// channel: (raw.params[1]),
+// //topic
+// message: (raw.params[2])
+// }));
+// });
+//
+// /*
+// * Handler for names.
+// * There can be multiple such calls as the names are retrieved, 353
+// */
+// irc.addListener('353', function (raw) {
+// client.send(JSON.stringify({
+// messagetype: "names",
+// //nick
+// from: (raw.params[0]),
+// //channel
+// channel: (raw.params[2]),
+// message: "",
+// //users as a space delimited string
+// users: (raw.params[3].split(" "))
+// }));
+// });
+//
+// /*
+// * Handler for end of names list, 366
+// */
+// irc.addListener('366', function (raw) {
+// client.send(JSON.stringify({
+// messagetype: "endnames",
+// //nick
+// from: (raw.params[0]),
+// //channel
+// channel: (raw.params[1]),
+// }));
+// });
+//
+// /*
+// * Handler for quitting
+// * This event will not be triggered after an irc.quit() call
+// */
+// irc.addListener('quit', function (message) {
+// client.send(JSON.stringify({
+// messagetype: "quit",
+// from: (message.person.nick),
+// channel: (message.params[0])
+// }));
+// });
+//
+// /*
+// * Handler for parting the channel, while remaining connected to the irc server
+// */
+// irc.addListener('part', function (message) {
+// client.send(JSON.stringify({
+// messagetype: "part",
+// from: (message.person.nick),
+// channel: (message.params[0])
+// }));
+// });
+//
+// /*
+// * Handler for server reporting nick change
+// */
+// irc.addListener('nick', function (message) {
+// var prevNick = message.person.nick,
+// newNick = message.params[0];
+// /*
+// * if ever this client will send commands, the code below will be needed
+// *
+// for (var i = 0; i < webUsers.length; i++) {
+// if (webUsers[i] == prevNick) {
+// webUsers[i] = newNick;
+// bWebUsersDirty = true;
+// break;
+// };
+// };
+// */
+// client.send(JSON.stringify({
+// messagetype: "nick",
+// from: prevNick,
+// channel: "",
+// message: newNick
+// }));
+// });
+//
+// /*
+// * Handler for irc error 433: nick already in use.
+// * We use this particular handler for the login screen
+// */
+// irc.addListener('433', function (message) {
+// client.send(JSON.stringify({
+// messagetype: "433",
+// //rejected nick
+// from: (message.params[1]),
+// //the irc server as channel
+// channel: message.server,
+// //the rejection message, usually "Nickname is already in use."
+// message: (message.params[2])
+// }));
+// });
+//
+// /*
+// * Handler for all irc server errors
+// * This has nothing to do with the eventual irc-js implementation errors
+// * Handles all error messages but 433 handled above
+// */
+// for (var err = 400; err < 600; err++) {
+// if (err != 433) {
+// irc.addListener(err, function (raw) {
+// client.send(JSON.stringify({
+// messagetype: "notice-err",
+// from: "",
+// channel: "",
+// message: raw.raw
+// }));
+// }); //addListener
+// }; //if
+// }; //for
+//
+// /*
+// * Handler for our own client
+// * e.g., timeout
+// */
+// irc.addListener('error', function () {
+// client.send(JSON.stringify({
+// messagetype: "error"
+// }));
+// });
View
78 public/js/tcp-client.js
@@ -0,0 +1,78 @@
+/*
+ * Based on:
+ * https://github.com/bgaff/tcp.js
+ * https://github.com/bgaff/vnc.js
+ * http://engineering.linkedin.com/javascript/vncjs-how-build-javascript-vnc-client-24-hour-hackday
+ */
+
+var Client = function (host, port) {
+ this.host = host;
+ this.port = port;
+ this.webUAIsConnected = false;
+ this.endpointIsConnected = false;
+ this.callbacks = {};
+ return this;
+}
+
+Client.prototype.connect = function () {
+ var that = this;
+
+ if (typeof this.socket === "undefined" || this.socket === null) {
+ this.socket = io.connect("http://" + window.location.host, {"reconnect": false})
+ } else {
+ if (!this.socket.socket.connected)
+ socket.socket.reconnect();
+ }
+
+ this.socket.on("connect", function () {
+ that.webUAIsConnected = true;
+ that.socket.send(JSON.stringify({action: "connect", host: that.host, port: that.port}));
+ });
+
+ this.socket.on("disconnect", function () {
+ that.webUAIsConnected = false;
+ that.endpointIsConnected = false;
+ that.emit("error", "the socket connection to UA was lost");
+ });
+
+ this.socket.on("message", function (data) {
+ data = JSON.parse(data);
+ switch (data.action) {
+ case "connected":
+ that.endpointIsConnected = true;
+ that.emit("connected");
+ break;
+ case "data":
+ that.emit("data", {data: data.data});
+ break;
+ case "closed":
+ that.endpointIsConnected = false;
+ that.emit("closed");
+ default:
+ }
+ });
+
+ return this;
+}
+
+Client.prototype.disconnect = function () {
+ if (this.webUAIsConnected)
+ this.socket.send(JSON.stringify({action: "disconnect"}));
+}
+
+Client.prototype.send = function (data1) {
+ if (this.webUAIsConnected && this.endpointIsConnected) {
+ this.socket.send(JSON.stringify({action: "data", data: data1}));
+ }
+}
+
+Client.prototype.emit = function (event, param) {
+ if (typeof this.callbacks[event] === "function")
+ this.callbacks[event].call(this, param);
+}
+
+Client.prototype.on = function (event, callback) {
+ if (typeof callback === "function")
+ this.callbacks[event] = callback;
+ return this;
+}
View
72 tcp-proxy.js
@@ -0,0 +1,72 @@
+/*
+ * Based on:
+ * https://github.com/bgaff/tcp.js
+ * https://github.com/bgaff/vnc.js
+ * http://engineering.linkedin.com/javascript/vncjs-how-build-javascript-vnc-client-24-hour-hackday
+ */
+
+var Proxy = function (client) {
+ //create the socket to connect to remote server on behalf of the client
+ var net = require("net");
+ var socket = new net.Socket();
+ socket.setEncoding("utf8");
+ var socketIsConnected = false;
+ var clientIsConnected = true; //at this stage this can be only true
+
+ socket.on("end", function () {
+ socketIsConnected = false;
+ if (clientIsConnected)
+ client.send(JSON.stringify({action: "closed"}));
+ });
+
+ socket.on("connect", function () {
+ socketIsConnected = true;
+ console.log("socket connected");
+ if (clientIsConnected)
+ client.send(JSON.stringify({action: "connected"}));
+ });
+
+ socket.on("data", function (data) {
+ console.log("data arrived:" + data + ", length: " + data.length );
+ if (clientIsConnected)
+ client.send(JSON.stringify({action: "data", data: data}));
+ });
+
+ //client related
+
+ client.on("disconnect", function () {
+ clientIsConnected = false;
+ if (socketIsConnected) {
+ socketIsConnected = false;
+ socket.destroy();
+ }
+ console.log("client disconnected");
+ });
+
+ client.on("message", function (message) {
+ msg = JSON.parse(message);
+ switch (msg.action) {
+ case "connect":
+ console.log("connect request received: " + msg.host + ":" + msg.port);
+ socket.connect(msg.port, msg.host);
+ break;
+ case "disconnect":
+ console.log("disconnect request received");
+ if (socketIsConnected)
+ socket.end();
+ break;
+ case "data":
+ console.log("data request received");
+ if (socketIsConnected) {
+ console.log(msg.data);
+ socket.write(msg.data);
+ }
+ break;
+ default:
+ break;
+ }
+ });
+}
+
+//export proxy
+module.exports = Proxy;
Please sign in to comment.
Something went wrong with that request. Please try again.