laravel,socketio和redis聊天应用程序,无法在页面重新加载后发出第一个请求以向其所有者发送消息吗?

时间:2018-11-13 13:38:53

标签: php laravel-5 redis socket.io

很长一段时间以来,我一直在试图解决这个问题,但是我什么也没发现, 我正在尝试使用构建一个简单的私人聊天应用程序

  • Laravel
  • Socketio
  • Redis,

我建立了聊天室,但有一个尚无法修复的错误, 问题是当我第一次打开聊天或在发送第一条消息时重新加载页面时,它会在正确的时间显示给接收者,但不会显示给所有者,尽管这是同时发送给两个用户的,但其他所有消息都会显示在正确的时间由两个用户决定,这是代码, 而且errorevent的功能相同,应该将错误消息发送给它的所有者,但不会通过socketio发送第一条消息。

server.js

var app = require('express')();
var http = require('http').createServer(app);
var io = require('socket.io')(http);
var Redis = require('ioredis');
var redis = new Redis();
var rediserror = new Redis();



redis.psubscribe('private-message-channel.*' , function(err , count) {
    console.log('error is '+err+' and count is '+count);
});

redis.on('pmessage' , function(pattern ,channel , message) {
    console.log('channel is '+channel+' and message is '+message);
    message = JSON.parse(message);

    io.emit(channel+':'+message.event , message.data);
});    

rediserror.psubscribe('private-error-channel.*' , function(err , count) {
    console.log('error is '+err+' and count is '+count);

});

rediserror.on('pmessage' , function( pattern ,channel , message) {
    console.log("channel is " + channel + " and message is: " + message);

    message = JSON.parse(message);
    io.emit(channel+':'+message.event , message.data);
});


var redischatchannel = new Redis();

redischatchannel.psubscribe('private-chat-channel.*' , function(err , count){
    console.log('error is '+err+' and count is '+count);
});

redischatchannel.on('pmessage' , function(pattern , channel , message) {
    console.log("channel is "+channel +" and message is: "+message);
    message = JSON.parse(message);


        io.emit(channel+':'+message.event , message.data);

});

http.listen(3000, function () {
    console.log('server lisening at port 3000');
});

chatroom.blade.php

@extends('layouts.app')

@section('content')

@if(!$messages)

    <h3>No Messages in your chat with {{$to->name}} yet</h3>
@else
    <div id="msgs">
    @foreach($messages as $message)
        <p><em><b>{{$message->fromusername}}</b></em> : {{$message->body}}</p>
        <hr>
    @endforeach
    </div>
@endif

<form id="chatform" >
<div class="form-group">
<input type="text" id="body"/>
</div>

<div class="form-group">
    <input type="submit" class="btn btn-primary" value="Send" />
</div>
</form>


@endsection

@section('script')
<script>

var socket = io('http://localhost:3000');


    socket.removeAllListeners(`private-chat-channel.{{$chatid}}.{{auth()->user()->id}}:App\\Events\\ChatEvent`);
    socket.on(`private-chat-channel.{{$chatid}}.{{auth()->user()->id}}:App\\Events\\ChatEvent` , function(msg){
        //console.log(msg);
        $('#msgs').append(`<p><em><b>${msg.data.fromusername}</b></em> : ${msg.data.body}</p><hr>`)
    });

    $('#chatform').submit(function(e) {
        e.preventDefault();
        var body = $('#body').val();
        var chatid ={{$chatid}} ;
        axios.post('/store-message' , {
            body:body,
            chatid:chatid
        }).then( function(response){
            console.log(response);
            var message=response;
            socket.removeAllListeners(`private-message-channel.${message.data.from}.${message.data.to}:App\\Events\\MessageEvent`);
            socket.on(`private-message-channel.${message.data.from}.${message.data.to}:App\\Events\\MessageEvent` , function(msg) {
             console.log(msg);
                $('#msgs').append(`<p><em><b>${msg.data.fromusername}</b></em> : ${msg.data.body}</p><hr>`);
                $('#body').val('');
            });
        }).catch(function(error){
            socket.removeAllListeners(`private-error-channel.{{auth()->user()->id}}:App\\Events\\ErrorMessage`);
            socket.on(`private-error-channel.{{auth()->user()->id}}:App\\Events\\ErrorMessage` , function(msg){
                console.log(msg);
            });
            console.error(error);
        });
    })

</script>
@endsection
聊天控制器中的

store_message方法

public function store_message(Request $request)
{
    $validator = Validator::make($request->all() , [
        'chatid' => 'required',
        'body' => 'required'
    ]);

    if($validator->fails())
    {
        event(new ErrorMessage( auth()->user() ,$validator->errors()));

        return response()->json(['errors' => $validator->errors()] , 400);
    }
    //dd($request);
    if(!Chat::find($request->input('chatid')))
    {
        event(new ErrorMessage( auth()->user() ,'chat not found'));
        return response()->json(['error'=>'error chat not found'] , 400);
    }

    $chat = Chat::find($request->chatid);

    if($chat['user1_id'] == auth()->user()->id)
    {
        $to = $chat['user2_id'];
    } elseif($chat['user2_id'] == auth()->user()->id)
    {
        $to = $chat['user1_id'];
    }
    //dd($to);
    $message = new Message;
    $message->chat_id = $request->chatid;
    $message->from = auth()->user()->id;
    $message->to = $to;
    $message->fromusername= auth()->user()->name;
    $message->tousername = User::find($to)->name;
    $message->body = $request->body;
    $message->save();
    event(new MessageEvent(auth()->user() , $message));
    event(new ChatEvent($request->chatid , $to ,$message));
    return $message;
}

MessageEvent.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\User;

class MessageEvent implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $data;
    public $user;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(User $user , $data )
    {
        $this->data = $data;
        $this->user = $user;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('message-channel.'.$this->user->id.'.'.$this->data->to);
    }
}

ErrorEvent.php

<?php

namespace App\Events;

use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use App\User;

class ErrorMessage implements ShouldBroadcast
{
    use Dispatchable, InteractsWithSockets, SerializesModels;

    public $data;
    public $user;
    /**
     * Create a new event instance.
     *
     * @return void
     */
    public function __construct(User $user , $data)
    {
        $this->user = $user;
        $this->data = $data;
    }

    /**
     * Get the channels the event should broadcast on.
     *
     * @return \Illuminate\Broadcasting\Channel|array
     */
    public function broadcastOn()
    {
        return new PrivateChannel('error-channel.'.$this->user->id);
    }
}

0 个答案:

没有答案