我正在尝试用宅基地上的laravel 5.4,laravel-echo,redis和socket-io创建一个实时聊天应用程序。
请检查下面的代码,然后检查我的问题
ChatConversation事件:
class ChatConversation implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
public $user;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct(Chat $message, User $user)
{
$this->message = message;
//Người gửi
$this->user = $user
}
/**
* Get the channels the event should broadcast on.
*
* @return Channel|array
*/
public function broadcastOn()
{
return new PresenceChannel('chatroom');
}
}
我的web.php:
Route::post('/privatechat/{id}/{receiver_id}', function(){
$user = Auth::user();
$room_id = request()->segment(5);
$rec = request()->segment(6);
$message = Chat::create([
'chat_room' => $room_id,
'message' => request()->get('message'),
'sender_id' => $user->id,
'receiver_id' => $rec
]);
broadcast(new ChatConversation($message, $user));
return ['status' => 'OK'];
})->middleware('auth');
我的聊天视频设置:
const app = new Vue({
el: '#app',
data: {
messages: [],
sendClass: 'chat-send'
//Điều kiện
},
methods: {
addMessage(message) {
this.messages.push(message);
axios.post(url_post, message);
/*.then(function (response) {
//swal('Tuyệt vời! Work like a charm!');
console.log(response);
})
.catch(function (error) {
console.log(error);
});*/
}
},
created() {
var u = url;
axios.get(u).then(response => {
//console.log(response);
this.messages = response.data;
});
/*Echo.join('chatroom')
.here()
.joining()
.leaving()
.listen('ChatConversation', (e) => {
console.log(e);
})*/
Echo.join('chatroom')
.listen('ChatConversation', (e) => {
console.log(e);
})
}
});
我的bootstrap.js
import Echo from "laravel-echo"
window.Echo = new Echo({
broadcaster: '../socket.io-client/dist/socket.io',
host: window.location.hostname + ':6001'
});
我的laravel-echo-server.json
"devMode": true,
"host": null,
"port": "6001",
"protocol": "http",
"socketio": {},
"sslCertPath": "",
"sslKeyPath": ""
我的第一个问题是当我使用此脚本访问客户端库时:
src =“// {{Request :: getHost()}}:6001 / socket.io / socket.io.js
我收到此错误GET http://hgc.develop:6001/socket.io/socket.io.js net :: ERR_CONNECTION_REFUSED 所以我不得不从凉亭下载插座并将上面的行更改为
<script src="{{ asset('js/socket.io-client/dist/socket.io.js') }}"></script>
我的第二个问题是,当我进入聊天应用程序页面时,控制台会向我显示以下错误:
app.js:35246 TypeError:无法读取未定义属性'presenceChannel'
app.js:15520 Uncaught(in promise)TypeError:无法读取未定义的属性'socketId'
还有一个,我按照本教程创建聊天应用程序:https://www.youtube.com/watch?v=8aTfMHg3V1Q但我使用的是Redis和Socket.io而不是Pusher
我的代码有什么问题?我该如何处理这些问题?
答案 0 :(得分:2)
我终于设法解决了这个问题。我仔细查看了JS文件并设法将其归结为the code in this line如果Laravel channels.php检查谁可以收听某个频道而没有实际发生错误try catch
部分这样的事实&#39 ; t应该返回用户模型实例。
Channels.php中的类似内容会抛出该错误:
Broadcast::channel('users', function ($user) {
if($user->type == 'admin'){
return $user;
}else{
return false;
}
});
如果$user
没有通过if
检查,Laravel将返回false
。由于它没有返回JSON而只是假,我认为它应该记录响应主体没有通过JSON.parse()
函数,所以你可以在终端中看到它。像这样:
try {
body = JSON.parse(response.body);
} catch (e) {
Log.warning('Response body provided is not expected JSON. Response body provided ${response.body}');
body = response.body;
}
这样我们就可以看出Laravel是否还没有返回用户模型实例。
因此,当您没有按预期获得用户模型实例时,没有用于将sockedId附加到代码的用户对象,因为它未定义。从来没有任何JSON来制作对象。
如果您没有获取用户实例而不是尝试附加套接字ID,我认为代码应该停止尝试连接到状态或私有通道。
无论如何,要真正返回用户,请确保您已登录using Laravel's Auth system.如果您没有使用它,则可能需要做一些工作才能使其正常工作。如果您没有使用它,请this function in Laravel will throw a 403 error because it can't find you to be logged in。
我不得不将使用提供程序检查密码哈希算法的函数写入自定义算法,这样我就不会弄乱Laravel核心并使用户模型扩展Laravel正在寻找的类。
然后在你的channels.php文件中,确保检查你是否正在通过auth检查Broadcaster.php文件实际返回回调函数中的$ user。像这样:
Broadcast::channel('users', function ($user) {
return $user;
});
这是一个超级简单的私人/在线频道,但有一个登录用户并返回$ user,这不会抛出此错误。
另外,请确保您在Echo实例中调用socket.io,如下所示:
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});