Сервер — это простая машина, которая прослушивает входящий запрос со стороны клиента, соответствующим образом обрабатывает этот запрос, отправляет правильный ответ и повторяет один и тот же процесс столько раз, сколько необходимо.

Для производства мы используем несколько удаленных серверов, но когда мы что-то разрабатываем, нам нужно создать сервер, который действительно слушает ваши запросы и ведет себя так же. мы делаем это, говоря вашей машине вести себя как сервер.

Если вы не знаете, как сделать его с помощью Nodejs, то эта статья для вас. Если вы знаете, как создать базовый сервер, я бы посоветовал вам все же прочитать его один раз, кто знает, может быть, вы узнаете что-то новое…

Для создания сервера в Nodejs у нас есть два варианта, либо можно использовать http module, а то у нас express. Стоит отметить, что Express в первую очередь предназначен для создания TCP-серверов и не предоставляет встроенной поддержки для создания UDP-серверов. Сегодня мы в основном сосредоточимся на TCP-серверах.

TCP-сервер – это сетевой сервер, использующий протокол управления передачей (TCP) для установления надежного, упорядоченного и защищенного от ошибок соединения между клиентом и сервером через сеть.

const express = require('express');
const app = express();

app.use(express.json());
app.post('/api/users', (req, res) => {
  const user = req.body;
  // do something with user data
  res.send('User created successfully');
});

app.listen(3000, () => {
  console.log('Server started on port 3000');
});

Вот так выглядит простой серверный код в наших экспресс-приложениях. Мы знаем, что этот код создаст сервер на нашем локальном компьютере, который мы затем будем прослушивать на порту 3000.

прежде чем мы продолжим, позвольте мне немного объяснить вам этот код.

  1. нам нужно было импортировать экспресс в файл, чтобы использовать его.
  2. Затем нам нужно было вызвать экспресс-функцию, которая создала бы наше приложение.
  3. Затем нам нужно проанализировать наши входящие запросы, app.use() это глобальное промежуточное ПО, и express.json() функция, которая будет анализировать все входящие запросы в удобочитаемые объекты или простые объекты javascript.
  4. Причина этого в том, что дата поступает на наш сервер в виде chunks. На самом деле для этого существует процесс под названием Data Serialization и Data de Serialization, который я не буду рассматривать в этой статье.
  5. app.post() пойдет по пути или маршруту, или как вы это называете. а затем функцию для обработки запроса, поступающего по этому маршруту или пути, или тому, как вы это называете.
  6. Затем мне нужно на самом деле прослушивать этот сервер на порту, куда мы можем отправить запрос, который в нашем случае равен 3000.
const express = require("express");
const app = express();

const users = [];

app.use(express.json());
app.post("/api/users", (req, res) => {
  const user = req.body;
  console.log(user);
  users.push(user);
  // do something with user data
  res.send("User created successfully");
});

app.listen(3000, () => {
  console.log("Server started on port 3000");
});

Я обновил этот же код, чтобы зарегистрировать входящего пользователя и сохранить его.

Экспресс-сервер — это, по сути, HTTP-сервер узла, который улучшен за счет использования некоторых функций, называемых промежуточным программным обеспечением…

Промежуточное ПО просто выполняет некоторую операцию над объектом запроса, прежде чем отправить его следующей функции, то есть функции, которую мы пишем для фактической обработки входящего запроса.

Чтобы понять это. давайте также создадим HTTP-сервер. Поскольку экспресс использует это за кулисами. для этой цели у нас есть встроенный модуль HTTP в узле, давайте воспользуемся им.

const http = require('http');

const server = http.createServer((req, res) => {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello World!\n');
});

server.listen(3000, () => {
  console.log('Server started on port 3000');
});

Это создаст простой HTTP-сервер, с которым мы можем взаимодействовать через порт 3000 на нашем локальном хосте, работа в основном такая же. Как и на экспресс-сервере.

Давайте добавим несколько методов для разных маршрутов, чтобы увидеть, как это работает на самом деле.

const http = require("http");

const server = http.createServer((req, res) => {
    if (req.method === 'GET' && req.url === '/') {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('Hello World!');
      }
});

server.listen(3000, () => {
  console.log("Server started on port 3000");
});

На HTTP-сервере нам действительно нужно проверять как маршруты, так и методы, чтобы фактически обрабатывать входящие запросы. Ответ на это будет выглядеть примерно так.

Это хорошо и все такое, но давайте посмотрим, что произойдет, когда мы попытаемся обработать почтовый запрос на HTTP-сервере.

const http = require("http");

const server = http.createServer((req, res) => {
  if (req.method === "GET" && req.url === "/") {
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("Hello World!");
  }

  if (req.method === "POST" && req.url === "/user") {
    console.log(req.body);
    res.end("user saved!!");
  }
});

server.listen(3000, () => {
  console.log("Server started on port 3000");
});

Итак, что здесь происходит, так это то, что наш сервер как бы зависает, причина этого в том, что мы на самом деле не получаем объект body в запросе. и, следовательно, мы получаем здесь undefined, поскольку body object не существует в request object. следовательно, res.end() функция никогда не вызывается, если эта функция не вызывается, это означает, что мы еще не отправили ответ, поэтому это происходит.

Express решает эту проблему за нас, помните, когда мы express.json() сделали это на нашем экспресс-сервере? Теперь давайте обработаем это на нашем HTTP-сервере.

const http = require("http");

const server = http.createServer((req, res) => {
  if (req.method === "GET" && req.url === "/") {
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("Hello World!");
  }

  if (req.method === "POST" && req.url === "/user") {
    let body = "";
    req.on("data", (chunck) => {
      console.log(chunck);
      body += chunck;
    });

    req.on("end", () => {
      console.log(body);
      res.end("user saved");
    });
  }
});

server.listen(3000, () => {
  console.log("Server started on port 3000");
});

Что я на самом деле здесь делаю, так это прослушиваю определенные события и соответствующим образом их обрабатываю. Я даже зарегистрировал данные фрагмента, которые мы получили в запросе, и добавил их в тело, и когда запрос завершается, это означает, что фрагмента больше нет.

Express делает всю эту работу за нас, как вы можете видеть req.end(), наше тело напрямую преобразуется в объект. то же самое нужно сделать для параметров запроса и пути, их реализации могут немного отличаться.

Я попытался выяснить, почему нам не нужно было здесь анализировать тело в JSON, ближе всего я узнаю, что, поскольку я уже отправлял данные в виде объекта JSON, следовательно, его не нужно было анализировать ( Я не уверен в этом, дайте мне знать в комментариях). Поэтому лучше всего разобрать его вручную, используя JSON.parse(body) .

За кулисами http module он использует другой модуль под названием net module для создания сервера. Модуль net — это низкоуровневый сетевой модуль в Node.js, который предоставляет асинхронный сетевой API для создания потоковых серверов TCP или IPC (и клиентов).

Он использует сокеты для поддержания соединения между клиентом и сервером. сокеты используются для обработки связи между сервером и клиентом.

const net = require('net');

const server = net.createServer((socket) => {
  console.log('Client connected.');

  socket.on('data', (data) => {
    console.log(`Received data from client: ${data}`);
    socket.write('Hello from server!');
  });

  socket.on('end', () => {
    console.log('Client disconnected.');
  });
});

server.listen(3000, '127.0.0.1', () => {
  console.log('Server started and listening on port 3000');
});

Я попытался запустить запрос на получение через порт 3000, но, поскольку я не обрабатывал их, давайте посмотрим, что выводится на терминал.

Что ж, это нормально, так как нам, вероятно, никогда не придется это использовать, учитывая выпускаемые новые библиотеки и фреймворки. Просто хорошо знать, что используется за кулисами.

Вывод: в этой статье мы увидели, как создать сервер в узле, что экспресс использует за кулисами для создания сервера, то есть модуль HTTP, и что модуль HTTP использует для создания сервера. Я надеюсь, что эта статья прольет свет на некоторые вещи для вас.