A simple Node.js telnet server/client library. It provides an interface similar to the standard net module (viz. createServer
and createConnection
) while abstracting option negotiation and providing handlers for some common options.
This example is a server that, once option negotiation finishes, says hello world to the client and then echos anything it receives back to the client. The client portion simply echos anything back to the server.
const telnetlib = require('telnetlib');
const server = telnetlib.createServer({}, (c) => {
c.on('negotiated', () => {
c.write('Hello World!');
});
c.on('data', (data) => {
c.write(data);
});
});
server.listen(9001);
const telnetlib = require('telnetlib');
const client = telnetlib.createConnection(
{
host: '127.0.0.1',
port: 9001
},
() => {
client.on('data', (data) => {
client.write(data);
});
}
);
- RFC1143 option negotiation
- Telnet option handlers for:
options
ObjectremoteOptions
Array Option codes we want enabled remotelylocalOptions
Array Option codes we want enabled locallyreceiveBuffermax
integer How large the receive buffer issubnegotiationBufferMax
integer How large the subnegotiation buffer is
handler
Function listener for theconnection
event.
Creates a new telnet server.
options
Objecthost
String Host the socket should connect toport
Integer Port the socket should connect toremoteOptions
Array Option codes we want enabled remotelylocalOptions
Array Option codes we want enabled locallyreceiveBuffermax
integer How large the receive buffer issubnegotiationBufferMax
integer How large the subnegotiation buffer is
handler
Function listener for theconnect
event.
A factory function which creates a net.Socket
, wraps it in a TelnetSocket
, initiates option negotiation, and returns the TelnetSocket
.
name
String The name of the telnet option.code
Integer The telnet option codehandler
TelnetOption Optional class that manages option
Register an option handler with the library.
- Extends: Stream.Stream
This class wraps a socket and manages object negotiation.
socket
net.Socket Socket object to wrapoptions
ObjectremoteOptions
Array Option codes we want enabled remotelylocalOptions
Array Option codes we want enabled locallyreceiveBuffermax
integer How large the receive buffer issubnegotiationBufferMax
integer How large the subnegotiation buffer is
Emitted when all option negotiations have been settled either through (dis)agreement or timeout.
optionCode
integer telnet option codeat
String value indicating where the option was enabled. Either'LOCAL'
or'REMOTE'
Emitted when an option is enabled.
optionCode
integer telnet option codeat
String value indicating where the option was disabled. Either'LOCAL'
or'REMOTE'
Emitted when an option is disabled.
option
- integer telnet option codetimeout
- integer timeout in milliseconds- Returns: Promise
Request that an option be enabled remotely.
option
- integer telnet option codetimeout
- integer timeout in milliseconds- Returns: Promise
Request that an option be disabled remotely.
option
- integer telnet option codetimeout
- integer timeout in milliseconds- Returns: Promise
Request that an option be enabled locally.
option
- integer telnet option codetimeout
- integer timeout in milliseconds- Returns: Promise
Request that an option be disabled locally.
code
- integer telnet option code- Returns: TelnetOption
Get the handler for the specified option.
This is the base class for option handlers.
at
String value indicating where option was enabled. Either'LOCAL'
or'REMOTE'
Called whenever the option is enabled. Intended to be overridden by subclasses.
at
String value indicating where option was disabled. Either'LOCAL'
or'REMOTE'
Called whenever the option is disabled. Intended to be overridden by subclasses.
buffer
Buffer contents of the subnegotiation
Called when a subnegotiation is received for an option. Intended to be overridden by subclasses.
- Extends:
telnetlib.TelnetOption
This class handles sending and receiving GMCP message.
packageName
String the name of the package the message belongs tomessageName
String the name of the messagedata
String | Number | Boolean | Object | Array The message data
Emitted when a GMCP message is received. packageName
and messageName
are normalized to lower case.
data
String | Number | Boolean | Object | Array The message data
As above, but instead of having packageName
and messageName
values they are included in the event name.
packageName
String the name of the packagemessageName
String the name of the messagedata
String | Number | Boolean | Object | Array The message data
Send a GMCP message.
- Extends:
telnetlib.TelnetOption
This class handles MCCP2 compression.
callback
Function optional callback
Only valid when MCCP is enabled locally. Sends a Z_FINISH
flush and forces MCCP off locally.
- Extends:
telnetlib.TelnetOption
This class handles sending and receiving window resize events.
data
Objectwidth
Integer The width reported by the client.height
Integer The height reported by the client.
Event emitted when a resize subnegotiation is received.
width
Integer The width to send. Default: 80height
Integer The height to send. Default: 24
Send a resize subnegotiation.
The main reason to extend this library would be to add additional option handlers. This can be easily done by subclassing TelnetOption
and registering it with the library using telnetlib.defineOption
before creating a server or client. As in:
const telnetlib = require('telnetlib');
const { where } = telnetlib.constants;
const ourOptionCode = 123;
class Something extends telnetlib.TelnetOption {
constructor(socket, code) {
super(socket, ourOptionCode);
}
enabled(at) {
if (at == where.LOCAL) console.log('this option was enabled locally');
}
disabled(at) {
if (at == where.LOCAL) console.log('this option was disabled locally');
}
subnegotiation(buffer) {}
}
telnetlib.defineOption('Something', ourOptionCode, Something);
This is similar to the simple example above, but instead of sending normal text back and forth across the connection, the same thing is done with GMCP messages.
const telnetlib = require('telnetlib');
const { GMCP } = telnetlib.options;
const server = telnetlib.createServer(
{
localOptions: [GMCP]
},
(c) => {
const gmcp = c.getOption(GMCP);
c.on('negotiated', () => {
gmcp.send('herp', 'derp', 42);
});
gmcp.on('gmcp/herp.derp', (data) => {
gmcp.send('herp', 'derp', data);
});
}
);
server.listen(9001);
const telnetlib = require('telnetlib');
const { GMCP } = telnetlib.options;
const client = telnetlib.createConnection(
{
host: '127.0.0.1',
port: 9001,
remoteOptions: [GMCP]
},
() => {
const gmcp = client.getOption(GMCP);
gmcp.on('gmcp/herp.derp', (data) => {
gmcp.send('herp', 'derp', data);
});
}
);
Using the blessed library this example renders a box with in the middle of the terminal. The box will resize to fit in clients that support NAWS.
const blessed = require('blessed');
const telnetlib = require('telnetlib');
const { ECHO, TRANSMIT_BINARY, NAWS, SGA } = telnetlib.options;
const server = telnetlib.createServer(
{
remoteOptions: [NAWS, TRANSMIT_BINARY, SGA],
localOptions: [ECHO, TRANSMIT_BINARY, SGA]
},
(c) => {
let screen;
c.on('negotiated', () => {
screen = blessed.screen({
smartCSR: true,
input: c,
output: c,
height: 80,
width: 24,
terminal: 'xterm',
fullUnicode: true,
cursor: {
artificial: true,
shape: 'line',
blink: true,
color: null
}
});
const box = blessed.box({
parent: screen,
top: 'center',
left: 'center',
width: '50%',
height: '50%',
content: 'Hello World',
border: 'line'
});
screen.render();
});
c.on('end', () => {
if (screen) screen.destroy();
});
}
);
server.listen(9001);