Building a Live Online Chat Room Based on Laravel + Swoole + Vue (P11)

Building a Live Online Chat Room Based on Laravel + Swoole + Vue (P11): Get History Chat History After Entering The Chat Room

In the last tutorial, we showed you how to get unread messages after the user logs in. Today we enter the chat room to see what happened in the chat room.

Chat room page initialization logic

The corresponding Vue component of the chat room page is resources/js/pages/Chat.vue, we open this file and see the initial rendering logic of the page and the interaction with the back-end interface.

First look created and mounted hook function of these two pages initialization phase calls.

created hook function

In the created process, it will be from the current page URL query string in room obtain information (Tips: URL chat room is http://webchats.test/#/chat?roomId=1):

async created() {
  const roomId = queryString(window.location.href, 'roomId');
  this.roomid = roomId;
  if (!roomId) {
    this.$router.push({path: '/'});
  }
  if (!this.userid) {
    // Prevent unlogged
    this.$router.push({path: '/login'});
  }
  const res = await url.getNotice();
  this.noticeList = res.data.noticeList;
  if (res.data.version !== res.data.version) {
    this.noticeBar = false;
  }
  this.noticeVersion = res.data.version;
},

If the room information is empty, it will jump to the homepage, if the user is not logged in, it will jump to the login interface.

Then call url.getNotice() to obtain information bulletin, corresponding to the back-end interface call is located resources/js/api/server.js:

// Request announcement
getNotice: () => Axios.get('https://s3.qiufengh.com/config/notice-config.js'

This piece does not belong to the core logic, and the specific details are ignored.

mounted hook function

Next, look at mounted logic function:

async mounted() {
  // WeChat rebound bug
  ios();
  this.container = document.querySelector('.chat-inner');
  // socket internal,this pointer to question
  const that = this;
  await this.$store.commit('setRoomDetailInfos');
  await this.$store.commit('setTotal', 0);
  const obj = {
    name: this.userid,
    src: this.src,
    roomid: this.roomid
  };
  socket.emit('room', obj);
  socket.on('room', function (obj) {
    that.$store.commit('setUsers', obj);
  });
  socket.on('roomout', function (obj) {
    that.$store.commit('setUsers', obj);
  });
  loading.show();
  setTimeout(async () => {
    const data = {
      total: +this.getTotal,
      current: +this.current,
      roomid: this.roomid
    };
    this.isloading = true;
    await this.$store.dispatch('getAllMessHistory', data);
    this.isloading = false;
    loading.hide();
    this.$nextTick(() => {
      this.container.scrollTop = 10000;
    });
  }, 500);

  this.container.addEventListener('scroll', debounce(async (e) => {
    if (e.target.scrollTop >= 0 && e.target.scrollTop < 50) {
      this.$store.commit('setCurrent', +this.getCurrent + 1);
      const data = {
        total: +this.getTotal,
        current: +this.getCurrent,
        roomid: this.roomid
      };
      this.isloading = true;
      await this.$store.dispatch('getAllMessHistory', data);
      this.isloading = false;
    }
  }, 50));

  this.$refs.emoji.addEventListener('click', function(e) {
    var target = e.target || e.srcElement;
    if (!!target && target.tagName.toLowerCase() === 'span') {
      that.chatValue = that.chatValue + target.innerHTML;
    }
    e.stopPropagation();
  });
},

Here is first initialized room total number of messages and information, and then Websocket channel routing server roominitiated the request, the server has to inform the user enters the room, and by listening to the client roomand roomoutreturns the server to receive the event message into the room and left the room:

socket.emit('room', obj);
socket.on('room', function (obj) {
    that.$store.commit('setUsers', obj);
});
socket.on('roomout', function (obj) {
    that.$store.commit('setUsers', obj);
});

In the callback function, we set the online user information of the room through Vuex.

In order to achieve this Laravel based authentication backend API interface, we are united in obj the new api_token field:

Of course, we need to calculate the property computed settings auth_token to make the above code to take effect:

computed: {
  ... // Other configurations
  ...mapState({
    userid: state => state.userInfo.userid,
    src: state => state.userInfo.src,
    auth_token: state => state.userInfo.token,
  })
},

Continue to look at mounted the logic followed by setTimeout the definition of a timer, mainly to get the chat room chat history from the server room, too, we have added in the Request field api_token fields:

const data = {
    total: +this.getTotal,
    current: +this.current,
    roomid: this.roomid,
    api_token: this.auth_token
};
this.isloading = true;
await this.$store.dispatch('getAllMessHistory', data);

getAllMessHistory The final request interface is defined in the rear end of resources/js/api/server.js the:

// Get all historical chats in the current room
RoomHistoryAll: data => Axios.get('/history/message', {
    params: data
}),

There is the request parameters of total the total number indicates that the message, current the current page (or the current screen news, because a large amount of information possible, here it is necessary to do the pagination process), roomid represents a room ID, api_token interface for authentication.

We will need to implement this historical chat history interface in the backend later, this is an HTTP request.

The last is the definition of event listening for two components: one is the processing of the chat window scroll operation, and the other is the processing after the Emoji icon is clicked. Note that when scrolling chat window also involves calling the chat history interfaces, which in fact we are very familiar pull-down refresh the phone App, we need here objparameter also joined api_token the field:

const data = {
    total: +this.getTotal,
    current: +this.getCurrent,
    roomid: this.roomid,
    api_token: this.auth_token
};

It can be seen that during the initialization phase of the chat room page, the two most important things are to establish a connection with the WebSocket server, tell it that the user has entered a certain room, and then obtain the historical chat history of this room and render it to the chat interface.

Next, we implement the corresponding Websocket interaction logic and HTTP routing interface on the back end.

History chat history backend interface

Let’s first implement the interface for obtaining historical chat records from the backend.

Create the controller first MessageController:

php artisan make:controller MessageController

The controller then write app/Http/Controllers/MessageController.php codes are as follows:

<?php
namespace App\Http\Controllers;

use App\Message;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class MessageController extends Controller
{
    /**
     * Get historical chat history
     * @param Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function history(Request $request)
    {
        $roomId = intval($request->get('roomid'));
        $current = intval($request->get('current'));
        $total = intval($request->get('total'));
        if ($roomId <= 0 || $current <= 0) {
            Log::error('Invalid room and page information');
            return response()->json([
                'data' => [
                    'errno' => 1
                ]
            ]);
        }
        // Get the total number of messages
        $messageTotal = Message::where('room_id', $roomId)->count();
        $limit = 20;  // 20 messages per page
        $skip = ($current - 1) * 20;  // From which message
        // Paging query messages
        $messageData = Message::where('room_id', $roomId)->skip($skip)->take($limit)->orderBy('created_at', 'desc')->get();
        // Return response
        return response()->json([
            'data' => [
                'errno' => 0,
                'data' => $messageData,
                'total' => $messageTotal,
                'current' => $current
            ]
        ]);
    }
}

This controller currently provides only history method that returns JSON formatted chat history.

Finally, we in the API route file routes/api.php definitions this route, the route after authentication is required to access, and because of this request will include api_token field, so certification will by auth:api done automatically Middleware:

Route::middleware('auth:api')->group(function () {
    ...
    Route::get('/history/message', 'MessageController@history');
});

Next, you can test the request on the front end. Since there is no message yet, the data returned is empty:

This is image title

In the next tutorial, we will write the code for users to enter and exit the room on the back end of the Websocket server, and update the online user information after entering and exiting, and push it to all online users in the chat room.

#laravel #swoole #vue

Building a Live Online Chat Room Based on Laravel + Swoole + Vue (P11)
7.10 GEEK