Desenvolvimento

23 fev, 2018

TypeScript: WebSocket

Publicidade

Dando continuidade à minha série de artigos sobre TypeScript, hoje irei demonstrar como trabalhar com WebSockets. Caso você nunca tenha trabalhado com WebSockets, eu recomendo a leitura do seguinte artigo:

Bom, o objetivo deste artigo será o desenvolvimento de um chat, utilizando TypeScript e o pacote Socket.IO. Para ser mais objetivo, eu irei pular a parte de configuração do projeto, partirei de um já criado e configurado com o TS. Caso você tenha interesse e clonar ele, segue o link no GitHub: TS-Standard.

Para os próximos passos será necessário a utilização de uma IDE, Quem acompanha os meus artigos, sabe da minha preferência pelo VS Code, mas como já mencionei antes, você pode utilizar um de sua preferência.

Com o projeto TS-Standard aberto na sua IDE, veja abaixo uma rápida explicação sobre os seus dois principais arquivos:

  • app.ts: arquivo bootstrap do projeto. Nele eu deixei configurado a importação do pacote express e a criação de uma rota default
  • server.ts: arquivo de configuração do servidor com a porta e o start

Para esse artigo, será necessário importar um pacote chamado socket.io. Para instalar ele no seu projeto, execute o seguinte comando no seu terminal:

npm i socket.io @types/socket.io --save
npm install copyfiles --save-dev

Configuração do projeto

O seu próximo passo será atualizar os arquivos mencionados acima com os seguintes trechos de código:

app.ts

import * as express from "express";
import { createServer, Server } from 'http';
import * as socketIo from 'socket.io';

class App {
    public app: express.Application;
    public server: Server;
    private io: SocketIO.Server;
    public PORT: number = 8100;

    constructor() {
        this.routes();
        this.sockets();
        this.listen();
    }

    routes() {
        this.app = express();
        this.app.route("/").get((req, res) => {
            res.sendFile(__dirname + '/index.html');
        });
    }

    private sockets(): void {
        this.server = createServer(this.app);
        this.io = socketIo(this.server);
    }

    private listen(): void {

        this.io.on('connection', (socket: any) => {
            console.log('a user connected');

            socket.on('chat message', function (msg) {
                console.log('message: ' + msg);
            });

            socket.on('disconnect', () => {
                console.log('user disconnected');
            });
        });
    }
}

export default new App();

Navegando pelo código acima nós temos:

  • 01 — 03: importação dos pacotes.
  • 09: definindo a porta que o projeto irá escutar.
  • 17–20: inicializando o express e definindo uma rota default. Note que ele está retornando um arquivo HTML. Ele será demonstrado abaixo.
  • 24–27: criando o server e inicializando o socket
  • 29–43: aqui nós estamos verificando o status da conexão dos nossos usuários, essa parte ficará mais clara na hora que você estiver testando o projeto

server.ts

import app from "./app";
import { Server } from 'http';

let port = process.env.PORT || app.PORT;

app.server.listen(port, function () {
    console.log(`server running in" + ${port}`);
});

No trecho de código acima, nós atualizamos a linha 6, passando para o server escutar a porta do nosso projeto.

index.html

<!doctype html>
<html>

<head>
    <title>Socket.IO chat</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }
        body {
            font: 13px Helvetica, Arial;
        }
        form {
            background: #000;
            padding: 3px;
            position: fixed;
            bottom: 0;
            width: 100%;
        }
        form input {
            border: 0;
            padding: 10px;
            width: 90%;
            margin-right: .5%;
        }
        form button {
            width: 9%;
            background: rgb(130, 224, 255);
            border: none;
            padding: 10px;
        }
        #messages {
            list-style-type: none;
            margin: 0;
            padding: 0;
        }
        #messages li {
            padding: 5px 10px;
        }
        #messages li:nth-child(odd) {
            background: #eee;
        }
    </style>
</head>

<body>
    <ul id="messages"></ul>
    <form action="">
        <input id="m" autocomplete="off" />
        <button>Send</button>
    </form>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
        $(function () {
            var socket = io();
            $('form').submit(function () {
                socket.emit('chat message', $('#m').val());
                $('#m').val('');
                return false;
            });
            socket.on('chat message', function (msg) {
                $('#messages').append($('<li>').text(msg));
            });
        });
    </script>
</body>

</html>

pakage.json

"scripts": {
"compile": "tsc -w",
"prestart": "copyfiles *.html dist/",
"start": "nodemon dist/server.js"
},
  • compile: chamada para o ts watch.
  • prestart: chamando o pacote copyfiles para copiar o arquivo .html para o diretório /dist.
  • start: utilizando o nodemon para subir e gerenciar o nosso server.

Testando

Agora, para testar, você irá precisar de dois terminais. Como estou utilizando o VS Code, irei deixar um rodando o comando compile e o outro o start. Caso você não esteja no VS, abra dois terminais e execute os comandos abaixo neles:

npm run compile 
-> para que o tscongig gere os arquivos .js
npm start 
-> ele irá executar o prestart, copiar o html para o dist e subir o server

Caso o comando npm start não tenha apresentado nenhum erro, você irá receber uma mensagem na sua console dizendo que o projeto está sendo executado na porta 8100. Esse passo pode ser visto na imagem abaixo:

Agora abra o endereço http://localhost:8100/ em duas abas do seu navegador e teste o envio e recebimento de mensagens. Você pode ver esse passo na imagem abaixo:

Com isso, nós finalizamos mais um artigo. Caso você tenha interesse em baixar o projeto desenvolvido aqui, segue o link dele no GitHub ts-websocket.