Noejs Learning Notes 3

Keywords: socket Google JSON encoding

Building TCP Server

Node implements HTTP server in the form of http.Server pseudoclass, which inherits from TCP server pseudoclass in. net Server.

TCP server declaration cycle

var server = require('net').createServer();
var port = 4001;
server.on('listening',function(){
    console.log('server is listening on port',port);
});
server.on('connection',function(socket){
    console.log('server has a new connection');
    socket.write('hello welcome');
    socket.end();
    server.close();
});
server.on('close',function(){
    console.log('server is closed');
});
server.on('error',function(){
    console.log('error occured:',err.message);
});
server.listen(port);

You can use pipes to write sockets to a writable stream: or to input sockets

var ws = require('fs').createWriteStream('myfile.txt');
require('net').createServer(function(socket){
    socket.pipe(ws);
}).listen(4001);
require('net').createServer(function(socket){
    var rs = require('rs').createReadStream('hello.txt');
    rs.pipe(socket);
}).listen(4001);

Set timeout time:

socket.setTimeout(60000,function(){
    socket.end('idle timeout,disconnecting bye!');
});
//Set the connection between the two terminals in a running state (by sending empty TCP packets with ACK flags to trigger an empty response from the other end)
socket.setKeepAlive(true);
//Specifies the delay time between the last received packet and the next remaining running packet
socket.setKeepAlive(true,10000);//10s

Before sending TCP packets, the kernel buffers the data. But it causes delays in sending data. If you want to force data to be sent immediately after the write command:

socket.setNoDelay(true);//Default isfalse.

Monitor connections:

socket.listen(port,host);//If no host is passed, a connection to any ip address is received

Building a complete TCP chat server

var server = require('net').createServer();
var sockets = [];
var port = 4001;
server.on('listening',function(){
    console.log('server is listening on port',port);
});
server.on('connection',function(socket){
    console.log('server has a new connection');
    sockets.push(socket);
    socket.on('data',function(data){
        console.log('got data:',data);
        sockets.forEach(function(otherSocket){
        if(otherSocket !== socket){
            otherSocket.write(data);
        }
    });
    });
    socket.on('close',function(){
        console.log('connection closed');
        var index = sockets.indexOf(socket);
        sockets.splice(index,1);
    });
});
server.on('close',function(){
    console.log('server is closed');
});
server.on('error',function(){
    console.log('error occured:',err.message);
});
server.listen(port);

Building HTTP Server

require('http').createServer(function(req,res){
    res.writeHead(200,{'Content-Type':'text/plain'});
    res.end('hello world');
}).listen(4000);

When listening for request events, the callback function gets an http.ServerRequest object as the first parameter, which contains the following attributes:
req.url: A string-like request url. (excluding mode, host name or port)
req.method: Request method, GET,POST,DELETE or HEAD
req.headers: This object has all the HTTP headers on the request.

The second parameter is the http.ServerResponse object. To write the response header, you can use the res.writeHead(status,headers) function. Headers are optional.

res.writeHead(200,{
    'Content-Type':'text/plain',
    'Cache-Control':'max-age=3600'
});
//Setting up the response head
res.setHeader(name,value);
//Delete the response header
res.removeHeader(headName);
//Write to the response body
res.write(string or buffer);

Transfer HTTP block response in stream form

HTTP block coding allows the server to continue sending data to the client without sending data size, i.e. it does not send a Content-Length response header, but a Transfer-Encoding:chunked. This response header allows the client to receive several blocks of data as the main body of the response and send a zero-length end block before the client ends the response.
Transfer files:

require('http').createServer(function(req,res){
    res.writeHead(200,{'Content-Type':'video/mp4'});
    var rs = require('fs').createReadStream('test.mp4');
    rs.pipe(res);
}).listen(4000);

Close the server: server.close();
Static file upload server:

var path = require('path'),
    fs = require('fs');

require('http').createServer(function(req,res){
    var file = path.normalize('.'+req.url);
    console.log('trying to serve',file);

    function reportError(err){
        console.log(err);
        res.writeHead(500);
        res.end('Internal server error');
    }
    fs.exists(file,function(exists){
        if(exists){
            fs.stat(file,function(err,stat){
                var rs;
                if(err){
                    return reportError(err);
                }
                if(stat.isDirectory()){
                    res.writeHead(403);res.end('forbidden');
                }else{
                    rs = fs.createReadStream(file);
                    rs.on('error',reportError);
                    res.writeHead(200);
                    rs.pipe(res);
                }
            });
        }else{
            res.writeHead(404);
            res.end('not found');
        }
    });
}).listen(4000);

Building TCP Client

Connect servers:

var net = require('net');
var port = 4000;
var host = localhost;
//If no host is passed, the default is localhost.callback, which is the callback function after the connection is established.
var conn = net.createConnection(port,host,callback);
conn.write('here is a string');
conn.write('SGVsbG8gV29ybGQH','base64');
conn.write(new Buffer('hello world'));
//Transferable a callback function
conn.write('hey',function(){console.log('data written');})
//Listen for data events to receive data from the server
conn.on('data',function(data){
    console.log('some data has arrived',data);
})
//Setting the encoding format
conn.setEncoding('base64');
//abort connection
conn.end();
//conn.end('bye bye','utf-8');
//Handling errors
conn.on('error',function(err){
    console.error('this error:'+error.message+',code:'+error.code);
});

Create HTTP requests

Create get request

var http = require('http');
var options = {
    host:"www.google.com",
    port:80,
    path:'/index.html'
};
http.get(options,function(res){
    console.log('got response:'+res.statusCode);
})

The http.request function returns an http.ClientRequest object. Use it to send data:

var options = {
    host:"www.google.com",
    port:80,
    path:'/index.html',
    method:"POST",
    headers:{
        "Accept":"text/json",
        "IF-Modified-Since":"Sat,28 Jan 2012 00:00:52 GMT"
    }
}
var request = http.request(options,function(response){
    console.log('STATUS:',response.statusCode);
    console.log('HEADERS::',response.headers);
    response.setEncoding('utf8');
    response.on('data',function(chunk){
        console.log('body:',chunk);
    });
});
request.write('this is a piece of data');
request.end();//To call the end() function, otherwise the response event cannot be triggered

The response event is triggered when the response of the HTTP server returns, but there is no response subject, so you can register the "data" event on the response to get the response subject.

Maintaining socket pool using HTTP.Agent

Node uses a proxy internally when creating HTTP requests. He maintains an active socket pool, which contains open but unused connections for the specified host name and port pair. At the end of the request, the socket emits a close event or an agent Remove event that is deleted from the broker's socket pool. If you want an HTP request to open for a long time, you can remove it from the socket pool.

req.on('socket',function(socket){
    socket.emit('agentRemove');
});

Node allows up to five open sockets per host-port on a given thread. agent:false can be passed through the option object to invalidate the agent's socket pool:

var options = {
    host:"www.google.com",
    port:80,
    path:'/index.html',
    method:"POST",
    agent:false
}
//Or change the maximum number allowed by modifying http.Agent.defaultMaxSockets. This modification is global.
http.Agent.defaultMaxSockets = 10;

HTTP proxy can also be specified when creating a request.

var agentOptions = {
    maxSockets:10
};
var agent = new Agent(options);
var requestOptions = {
    host:"www.google.com",
    port:80,
    agent:agent
};
var req = http.request(requestOptions);
req.end();

Simplifying HTTP requests with third-party request module

var reuqest = require('request');
request('http://www.acme.com:4001/something?page=2',function(error,response,body));

An option object can be used instead of a URL string. Contains the following properties:
uri or url:

method:
headers:
qs:Attached as a query string to URL Name after-The value is right.
body:The request body must be a buffer or string.
form:Set the request body as a query string. Increase the content type of the request header to:application/x-www-form-urlencoded;charset=utf-8.
json:The request body is set to json Form, content type application/json.
followRedirect:Following a state code of 3 xx Response. Default is true.
maxRedirects:Maximum number of times to follow redirection, default 10.
onResponse:If so true Then the callback function will be in response The event is called when it occurs.
encoding:
pool:Represents the hash object of the request broker. If ignored, the global socket pool is used.
pool.maxSockets:
timeout:

Posted by ealderton on Mon, 01 Apr 2019 06:42:29 -0700