Download Laravel composer create-project –prefer-dist Laravel/Laravel Laravel_worker “5.8.*”

Download gatewayworker www.workerman.net/download/Ga…

Place the downloaded project in this path

Download gatewayclient

composer require workerman/gatewayclient
Copy the code

cnpm install

cnpm install
Copy the code

Listen for vUE file changes

npm run watch
Copy the code

The following errors may occur

You need to delete the node_modules directory

rm -rf node_modules
Copy the code

run

npm install vue-template-compiler --save-dev --production=false
cnpm install
npm run watch
Copy the code

Database Configuration

Creating a database

Configuration env.

DB_DATABASE=laravel_worker DB_USERNAME=root DB_PASSWORD=rootCopy the code

Table migration

php artisan migrate
Copy the code

The user

perform

php artisan make:auth
Copy the code

New users

Add three users aAAA BBBB CCCC

The browser input address: http://192.168.240.131:84/register

Add the following code to laravel_worker\app\ user.php

/ avatars * * * * @ return string * / public function avatars () {return 'https://source.unsplash.com/user/erondu/50x50'. }Copy the code

Creating an information table

php artisan make:model Message -m
Copy the code

Laravel_worker \database\migrations\2021_06_08_081347_create_messages_table.php Add the following code

public function up()
    {
        Schema::create('messages', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('user_id');
            $table->integer('room_id')->nullable();
            $table->text('content');
            $table->timestamps();
        });
    }
Copy the code

Executing migration commands

php artisan migrate
Copy the code

The user enters the chat room

ChatRoom Chat screen

Add the chatroom. vue file to laravel_worker, resources, js, components

<template> <div class="container"> <a href="? Room_id =1" class=" BTN BTN danger"> music </a> <a href="? Room_id =2" class=" BTN bTN-primary "> game </a> < HR class=" Divider "> <div class="row"> <div class=" col-MD-8 "> <div Class ="panel panel-default"> <div class="panel-heading"> chat room </div> <div class="panel-body"> <div class="messages"> <div class="media"> <div class="media-left"> <a href="#"> <img class="media-object img-circle"> </a> </div> <div class="media-body"> <p class="time">time</p> <h4 class="media-heading">name</h4> : content </div> </div> </div> </div> </div> </div> <div class="col-md-4"> <div class="panel panel-default"> <div <div > <div class="panel-body"> <ul class="list-group"> <li class="list-group-item"> <img class="img-circle"> user.name </li> </ul> </div> </div> </div> </div> <hr class="divider"> <form @submit.prevent="onSubmit"> <div class="form-group"> <label for="user_id"> Send to </label> <select class="form-control" Id ="user_id"> <option value=""> all </option> <option>user.name</option> </select> </div> <div class="form-group"> <label </label> <textarea class="form-control" rows="3" id="content"></textarea> </div> <button Type ="submit" class=" BTN bTN-dark "> submit </button> </form> </div> </template> <script> export default {data() {return {} }, created: function () { }, methods: {} } </script> <style scoped> .panel-body { height: 480px; overflow: auto; } .media-object.img-circle { width: 64px; height: 64px; } .img-circle { width: 48px; height: 48px; } .time { float: right; } .media { margin-top: 24px; } </style>Copy the code

D: phpstudy\WWW\laravel_worker\resources\js\app.js add code

/ / Vue.com registered components ponent (' chat room - 'the require (". / components/ChatRoom. Vue'). The default).Copy the code

D: \ phpstudy \ WWW \ laravel_worker \ resources \ views \ home. The blade. The PHP code

@extends('layouts.app')

@section('content')
    <chat-room></chat-room>
@endsection
Copy the code

Open a browser

http://192.168.240.131:84/home

Modifying the Socket Protocol

D: phpstudy\WWW\laravel_worker\socket\GatewayWorker\Applications\YourApp\start_gateway.php

$gateway = new gateway (" websocket: / / 0.0.0.0:8282 ");Copy the code

Modify Events. PHP

D:\phpstudy\WWW\laravel_worker\socket\GatewayWorker\Applications\YourApp\Events.php

public static function onConnect($client_id)
    {
        Gateway::sendToClient($client_id, json_encode(array(
            'type'      => 'init',
            'client_id' => $client_id
        )));
    }
public static function onMessage($client_id, $message)
   {
       
   }
Copy the code

Start the gatewayworker

cd socket/GatewayWorker
php start.php start
Copy the code

The client establishes a Websocket connection

< script > let ws = new WebSocket (ws: / / 192.168.240.131: '8282') export default {data () {return {}}, created: function () { ws.onmessage = (e) => { let data = JSON.parse(e.data) console.log(data) } }, methods: {} } </script>Copy the code

Browser console debug output

{type: "init", client_id: "7f0000010b5500000002"}
Copy the code

Enter a chat room

The front-end code

<template> <div class="container"> <a href="? Room_id =1" class=" BTN BTN danger"> music </a> <a href="? Room_id =2" class=" BTN bTN-primary "> game </a> < HR class=" Divider "> <div class="row"> <div class=" col-MD-8 "> <div Class ="panel panel-default"> <div class="panel-heading"> chat room </div> <div class="panel-body"> <div class="messages"> <div class="media" v-for="message in messages"> <div class="media-left"> <a href="#"> <img class="media-object img-circle" :src="message.avatar"> </a> </div> <div class="media-body"> <p class="time">{{message.time}}</p> <h4 class="media-heading">{{message.name}}</h4> : {{message.content}} </div> </div> </div> </div> </div> </div> <div class="col-md-4"> <div class="panel panel-default"> <div class="panel-body"> <ul class="list-group"> <li class="list-group-item"> <img class="img-circle"> user.name </li> </ul> </div> </div> </div> </div> <hr class="divider"> <form @submit.prevent="onSubmit"> <div class="form-group"> <label for="user_id"> Send to </label> <select class="form-control" Id ="user_id"> <option value=""> all </option> <option>user.name</option> </select> </div> <div class="form-group"> <label </label> <textarea class="form-control" rows="3" id="content"></textarea> </div> <button </button> </form> </div> </template> <script> let ws = new The WebSocket (ws: / / 192.168.240.131: '8282') export default {data () {return {' messages' : []}}, created: Function () {ws.onMessage = (e) => {let data = json.parse (e.ata) console.log(data) // If there is no type, To empty the let type = data. Type | | 'switch (type) {case "init" : axios. Post ('/init, {client_id: data. Client_id}) break; case "say": this.messages.push(data.data) break; default: console.log(data) } } }, methods: {} } </script> <style scoped> .panel-body { height: 480px; overflow: auto; } .media-object.img-circle { width: 64px; height: 64px; } .img-circle { width: 48px; height: 48px; } .time { float: right; } .media { margin-top: 24px; } </style>Copy the code

The back-end code

D: phpstudy\WWW\laravel_worker\routes\web.php

Route::post('/init', 'HomeController@init'); 
Copy the code

D:\phpstudy\WWW\laravel_worker\app\Http\Controllers\HomeController.php

<?php

namespace App\Http\Controllers;

use GatewayClient\Gateway;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class HomeController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
        Gateway::$registerAddress = '127.0.0.1:1238';
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Contracts\Support\Renderable
     */
    public function index()
    {
        return view('home');
    }

    public function init(Request $request)
    {
        //绑定用户
        $this->bind($request);

        //进入聊天室
        $this->login();
    }

    public function login()
    {
        $data = [
            'type' => 'say',
            'data' => [
                'avatar' => Auth::user()->avatar(),
                'name' => Auth::user()->name,
                'content' => '进入了聊天室',
                'time' => date('Y-m-d H:i:s')
            ]
        ];

        Gateway::sendToAll(json_encode($data));
    }

    public function bind($request)
    {
        $id = Auth::id();
        $client_id = $request->client_id;
        Gateway::bindUid($client_id, $id);
    }


}
Copy the code

Sending a Chat Message

The front-end code

<template> <div class="container"> <a href="? Room_id =1" class=" BTN BTN danger"> music </a> <a href="? Room_id =2" class=" BTN bTN-primary "> game </a> < HR class=" Divider "> <div class="row"> <div class=" col-MD-8 "> <div Class ="panel panel-default"> <div class="panel-heading"> chat room </div> <div class="panel-body"> <div class="messages"> <div class="media" v-for="message in messages"> <div class="media-left"> <a href="#"> <img class="media-object img-circle" :src="message.avatar"> </a> </div> <div class="media-body"> <p class="time">{{message.time}}</p> <h4 class="media-heading">{{message.name}}</h4> : {{message.content}} </div> </div> </div> </div> </div> </div> <div class="col-md-4"> <div class="panel panel-default"> <div class="panel-body"> <ul class="list-group"> <li class="list-group-item"> <img class="img-circle"> user.name </li> </ul> </div> </div> </div> </div> <hr class="divider"> <form @submit.prevent="onSubmit"> <div class="form-group"> <label for="user_id"> Send to </label> <select class="form-control" Id ="user_id"> <option value=""> all </option> <option>user.name</option> </select> </div> <div class="form-group"> <label </label> <textarea class="form-control" rows="3" id="content" V-model ="content"></textarea> </div> <button type="submit" class=" BTN bTN-dark "> </button> </form> </div> </template> <script> let ws = new The WebSocket (ws: / / 192.168.240.131: '8282') export default {data () {return {' messages' : [], 'content' : ',}}, created: Function () {ws.onMessage = (e) => {let data = json.parse (e.ata) console.log(data) // If there is no type, To empty the let type = data. Type | | 'switch (type) {case "init" : axios. Post ('/init, {client_id: data. Client_id}) break; case "say": this.messages.push(data.data) this.$nextTick(function () { $('.panel-body').animate({scrollTop: $('.messages').height()}) }) break; default: console.log(data) } } }, methods: { onSubmit() { axios.post('/say', {content: this.content}) this.content = '' }, } } </script> <style scoped> .panel-body { height: 480px; overflow: auto; } .media-object.img-circle { width: 64px; height: 64px; } .img-circle { width: 48px; height: 48px; } .time { float: right; } .media { margin-top: 24px; } </style>Copy the code

The back-end code

D:\phpstudy\WWW\laravel_worker\routes\web.php

Route::post('/say', 'HomeController@say');
Copy the code

D:\phpstudy\WWW\laravel_worker\app\Message.php

protected $guarded = [];
Copy the code

test

Open two browsers

Chat history

The front-end code

Just add the following code to the Switch

case "history":
    this.messages = data.data
    break;
Copy the code

The back-end code

D:\phpstudy\WWW\laravel_worker\app\Http\Controllers\HomeController.php

$this->bind($Request); $this->bind($Request); $this->history(); $this->login(); } /** * public function history() {$data = ['type' => 'history']; $messages = Message::with('user')->orderBy('id', 'desc')->limit(5)->get(); $data['data'] = $messages->map(function ($item, $key) { return [ 'avatar' => $item->user->avatar(), 'name' => $item->user->name, 'content' => $item->content, 'time' => $item->created_at->format('Y-m-d H:i:s') ]; }); $data['data'] = array_reverse(json_decode($data['data'], true)); Gateway::sendToUid(Auth::id(), json_encode($data)); }Copy the code

D:\phpstudy\WWW\laravel_worker\app\Message.php

New User Association

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
    //
    protected $guarded = [];

    public function user()
    {
        return $this->belongsTo('App\User');
    }
}

Copy the code

D:\phpstudy\WWW\laravel_worker\app\User.php

New Information Association

public function messages()
{
    return $this->hasMany('App\Message');
}
Copy the code

List of Online Users

The front-end code

<div class=" col-mD-4 "> <div class="panel panel-default"> <div class="panel-heading"> Chat room online user </div> <div class="panel-body"> <ul class="list-group"> <li class="list-group-item" v-for="user in users"> <img class="img-circle" :src="user.avatar"> {{user.name}} </li> </ul> </div> </div> </div>Copy the code
<div class="form-group"> <label for="user_id"> </label> <select class="form-control" Id ="user_id"> <option value=""> All </option> <option :value="user.id" v-for="user in users">{{user.name}}</option> </select> </div> <div class="form-group"> <label for="content"> </label> <textarea class="form-control" Rows ="3" id="content" V-model ="content"></ button type="submit" class=" BTN btn-dark"> </button> </form>Copy the code
data() {
    return {
        'messages': [],
        'content': '',
        'users': []
    }
},
    
case "users":
	this.users = data.data
break;
Copy the code

The back-end code

$this->bind($Request); $this->bind($Request); $this->history(); $this->users(); $this->login(); } public function users() { $data = [ 'type' => 'users', 'data' => Gateway::getAllClientSessions() ]; Gateway::sendToAll(json_encode($data)); } public function bind($request) { $id = Auth::id(); $client_id = $request->client_id; Gateway::bindUid($client_id, $id); Gateway::setSession($client_id, [ 'id' => $id, 'avatar' => Auth::user()->avatar(), 'name' => Auth::user()->name, ]); }Copy the code

The private chat

The front-end code

<div class="form-group"> <label for="user_id"> </label> <select class="form-control" Id ="user_id" V-model ="user_id"> <option value=""> All </option> <option :value="user.id" v-for="user in Users ">{{user.name}}</option> </select> </div> <div class="form-group"> <label for="content"> </label> <textarea class="form-control" rows="3" id="content" v-model="content"></textarea> </div> <button type="submit" Class =" BTN bTN-dark "> submit </button> </form>Copy the code
data() {
    return {
        'messages': [],
        'content': '',
        'users': [],
        'user_id': '',
    }
},
    
 methods: {
     onSubmit() {
         axios.post('/say', {content: this.content, user_id: this.user_id})
         this.content = ''
     },
 }
Copy the code

The back-end code

Public function say(Request $Request) {$data = ['type' => 'say', 'data' => [ 'avatar' => Auth::user()->avatar(), 'name' => Auth::user()->name, 'content' => $request->input('content'), 'time' => date('Y-m-d H:i:s') ] ]; / / private chat if ($request - > user_id) {$data [' data '] [' name '] = Auth: : the user () - > name. 'to'. The user: : find ($request - > user_id) - > name. 'said:'; Gateway::sendToUid(Auth::id(), json_encode($data)); Gateway::sendToUid($request->user_id, json_encode($data)); // Return; } Gateway::sendToAll(json_encode($data)); / / to save to the database Message: : create ([' user_id '= > Auth: : id (),' content '= > $request - > input (' content')]); }Copy the code

The room

The front-end code

<a href="? Room_id =1" class=" BTN BTN danger"> music </a> <a href="? Room_id =2" class=" BTN btn-primary"> game </a>Copy the code

The back-end code

public function index(Request $request) { $room_id = $request->room_id ? $request->room_id : '1'; session()->put('room_id', $room_id); return view('home'); } public function bind($request) { $id = Auth::id(); $client_id = $request->client_id; Gateway::bindUid($client_id, $id); Gateway::joinGroup($client_id, session('room_id')); Gateway::setSession($client_id, [ 'id' => $id, 'avatar' => Auth::user()->avatar(), 'name' => Auth::user()->name, ]); } public function say(Request $Request) {Message::create(['user_id' => Auth::id(), 'room_id' => session('room_id'), 'content' => $request->input('content') ]); }Copy the code
// set all Gateway::sendToAll(json_encode($data));Copy the code
// Change to Gateway::sendToGroup(session('room_id'), json_encode($data));Copy the code

User exit

The front-end code

case "logout":
	this.$delete(this.users, data.client_id)
break;
Copy the code

The back-end code

D:\phpstudy\WWW\laravel_worker\socket\GatewayWorker\Applications\YourApp\Events.php

You need to restart the socket service

@param int $client_id connection id */ public static function onClose($client_id) GateWay::sendToAll(json_encode([ 'type' => 'logout', 'client_id' => $client_id ])); }Copy the code

The heartbeat

The front-end code

case "ping":
    ws.send('pong');
    console.log(data)
break;
Copy the code

The back-end code

D:\phpstudy\WWW\laravel_worker\socket\GatewayWorker\Applications\YourApp\start_gateway.php

You need to restart the socket service

$gateway->pingInterval = 10; $gateway->pingData = '{"type":"ping"}';Copy the code