preface

  • Realizing bullet Screen Gadget Based on Electron + NodeJS + applets
  • Realizing bullet Screen Gadget Based on Electron + NodeJS + Small Program (Part 1)

The last two articles respectively introduced the product requirements and the realization of the Electron terminal. Interested friends can have a look at the previous articles. This article introduces the implementation of the server side.

Demand analysis

As mentioned in the previous article, the main task of the server side is to forward the data and generate the small program QR code.

To forward data, the message sent by the user on the small program side is pushed to the Electron receiver. Therefore, we need to create a WebSocket service. In this case, we chose to use the WS module.

To generate the small program QR code, we need to use the API of wechat. We will use the request module to make relevant requests to the wechat server.

Create the WebSocket service

The entry file code is as follows:

const WebSocketServer = require('ws').Server;
const port = require('./config').port;
const log4js = require('./helpers/logger');
const logger = log4js.Logger('APP');
const wsServer = new WebSocketServer({ port });

logger.info("Server listening on port:" + port);

wsServer.on('connection'.function (ws) {
    logger.debug('a client connect');

    ws.on('message', async function(message) {// message processing logic}); ws.on('close'.function () {
        logger.info('the ws broken');
    })

    ws.on('error'.function(error) { ws.close(); logger.error(error); })});Copy the code

The client connected to the service may be the small program sender or the Electron receiver, so we need to perform a simple type judgment on the received message.

According to the convention, if the message type is INIT, we consider it to be initialized by the receiver. The parameters passed include the UID of the receiving end. We will use this ID as a parameter to generate the small program TWO-DIMENSIONAL code with parameters.

Since we will use bullets in public places, we need to verify the content to prevent some remarks that do not conform to the core socialist values from appearing in the bullets. Here, we directly use the msgSecCheck interface of wechat.

ws.on('message', async function (message) {
    try {
        const data = JSON.parse(message);
        if (data.type === "INIT") {
            logger.info('Get qr code', data); Ws.danmuid = data.clientid; // Set the receiver's clientId as the connection identifier. Const result = await wechatService.getQrCode (data.clientid);if(result){
                const respMsg = {
                    type: 'qrcode', data: result } ws.send(JSON.stringify(respMsg)); }}else {
            logger.info('Received message', ws.danmuId, message); / / the message content security check const isSecurity = await WechatService. CheckContentSecurity (data. The content);if(isSecurity){// Forward the message to the corresponding receiver wsServer.clients.foreach (function (client) {
                    if(client.danmuId === data.scene && client.readyState === 1) { client.send(message); }}); } } } catch (error) { logger.error(error); }});Copy the code

Generate a small program two-dimensional code with parameters

Wechat provides three interfaces for generating QR codes, which are applicable to different application scenarios. See the official documentation for details

This project uses getWXACodeUnlimit API to obtain small program code. The small program code generated through this interface is permanently valid and the number is temporarily unlimited.

Request the address

POST https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=ACCESS_TOKEN
Copy the code

If the call is successful, it returns images *** binary content ***, if the request fails, it returns JSON data.

WTF, as stated in the official documentation, returns binary content, but why does my request return garbled characters?

Request () {request () {request ();

encoding – encoding to be used on setEncoding of response data. If null, the body is returned as a Buffer. Anything else (including the default value of undefined) will be passed as the encoding parameter to toString() (meaning this is effectively utf8 by default). (Note: if you expect binary data, you should set encoding: null.)

The default is UTF8, and if we want binary content, we need to set Encoding to NULL. The output is as follows:

Access_token acquisition and caching

Those who have experience in wechat development know that basically all wechat apis require access_token when requesting them. However, there is a limit to the number of times an access_token can be requested per day, beyond which it cannot be obtained and can only wait for tomorrow to come. So we need to cache the access_token.

Since our project is standalone deployment, we can simply store the Access_token in memory. Each time, we will judge whether the access_token in memory is expired or not. Otherwise, we will request the latest one from the wechat server and synchronously update it to the memory.

If multi-instance deployment is considered, access_token can be stored in Redis.

Log print

Lu Xun once said that no log service is playing rogue. Logs are an indispensable part of background services. Here we use log4JS to print logs.

Simplest use example:

var log4js = require('log4js');
var logger = log4js.getLogger();
logger.level = 'debug';
logger.debug("Some debug messages");
Copy the code

Please check the official documentation for details

GitHub project address

The project address

We will continue to sort out the end of the code put on GitHub, interested can refer to.

conclusion

This paper uses WS module to build a simple Websocket service, and uses Request for wechat API to obtain small program code. For log printing, we use Log4JS to record some key information.

In the next article, we will explore the implementation of small programs.

Above, if there are mistakes, welcome to correct!

@Author: TDGarden