Make a chat room with workerman

Time:2021-7-15

Why write this article?

I’ve learned workerman several times and failed every time. But this time, it took several hours to realize the function that was not done before. In fact, it has two simple functions: one-to-one message sending and broadcasting (group chat). This function has been implemented with spool for a long time. It’s also because I always wanted to use think worker before. I have to think about it by myself. The framework made by others may be a castrated version.

Don’t ask me why I don’t use spool, because workerman can run in windows.

(1) First of all, let’s talk about the installation of ThinkPHP + worker man.

Install thinkp5.1

composer create-project topthink/think=5.1.x-dev tp5andworkman

Install think worker

composer require topthink/think-worker=2.0.*

Direct installation of workerman

composer require workerman/workerman

(2) Let’s look at the code of think worker first

  • config/worker_server.php

  • Let’s start with an example of the server broadcasting a message, broadcasting a message every 10 seconds

'onWorkerStart'  => function ($worker) {

But in onmessage, we can’t get the $worker object, so we can’t broadcast the message.

'onMessage'      => function ($connection, $data) {

I tried all kinds of methods, but it didn’t seem to work

'onMessage'      => function ($connection, $data)use($worker) {

So we can only abandon the think worker framework encapsulated by ThinkPHP, and have to write (or modify the internal code of the framework) by ourselves

Modify the code inside the framework:/vendor/topthink/think-worker/src/command/Server.php, mainly adding the onmessage method itself

Use () is to pass external variables to the function for internal use, or useglobal $worker

$worker = new Worker($socket, $context);

In this way, we can get the $worker object

$worker->onMessage = function ($connection, $data)use($worker) { ... }

(3) $connection bind UID

In fact, you have already seen that $worker > connections gets the connections of all current users, and connections is one of them.

Record websocket connection time:

$worker->onConnect = function ($connection) {
    $connection->login_time = time();
};

Get websocket connection time:

$worker->onMessage = function ($connection, $data)use($worker) {
    $login_time = $connection->login_time;
};

From this, we can see that we can bind data to an attribute of $connection, for example:

$connection->uid = $uid;

When the JavaScript end successfully connects to the websocket server, it immediately sends its uid to the server binding

$worker->onMessage = function ($connection, $data)use($worker) {
    $origin = json_decode($data,true);
    if(array_key_exists('bind',$origin)){
        $connection->uid = $origin['uid'];
    }
};

(4) Unicast sending message, that is, custom sending

$worker->onMessage = function ($connection, $data)use($worker) {

So far, we have finished sending messages based on the workerman custom object.

Since the PHP file is stored in composer, you only need to copy the file and put it in theapplication/command, modify the namespace, and then save it to your own project

(5) Compare with spool

1. Workerman can run in Windows system, but spool can’t.

2. Workerman: $worker – > connections gets all connections and $connection – > ID gets its own connection ID; Spool: $server > connections gets all connections, and $connection > FD gets its own connection ID.

3. When the workerman starts, execute the onworkerstart method to write the timer to it; Swoole uses workerstart to start the timer.

Just for chat rooms or timers, workerman is more convenient.

(6) Project extension

  • Add the function of forbidding speech to the system;
  • Add user’s head image display;
  • Increase picture sending and display;
  • Expression display;

The results are as follows

Make a chat room with workerman

This work adoptsCC agreementReprint must indicate the author and the link of this article