laravel 使用 PHP 和 Websockets 的实时聊天应用程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42623684/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Real time Chat application with PHP & Websockets
提问by Gaurav Bakshi
I want to create chat application in a webapp where user can chat with different site users. This will be available on web and also on iOS.
我想在 webapp 中创建聊天应用程序,用户可以在其中与不同的站点用户聊天。这将在 Web 和 iOS 上可用。
Instead of using traditional polling technique (send ajax hit to server in 1 sec interval), i want to use websockets.
我想使用 websockets,而不是使用传统的轮询技术(以 1 秒的间隔向服务器发送 ajax 命中)。
Gone through couple of tutorials, but in all of them they have made PUBLIC GROUP chat. (Sample URL : https://www.sanwebe.com/2013/05/chat-using-websocket-php-socket)
经历了几个教程,但在所有教程中,他们都进行了公共群组聊天。(示例网址:https: //www.sanwebe.com/2013/05/chat-using-websocket-php-socket)
Can anyone have idea to how to develop private chat using PHP & Websockets.
任何人都可以知道如何使用 PHP 和 Websockets 开发私人聊天。
I have basic idea of websockets but how to use them to publish data on specific channel? And if we have 40 users so do we need to create 40 different channels?
我有 websockets 的基本概念,但如何使用它们在特定频道上发布数据?如果我们有 40 个用户,那么我们是否需要创建 40 个不同的频道?
Thanks in advance.
提前致谢。
回答by invisal
There are not much different from doing one single global chat and multiple private channel. First, you need to design a protocol. Let create a simple protocol:
与做一个全球聊天和多个私人频道没有太大区别。首先,您需要设计一个协议。让我们创建一个简单的协议:
// client send to server
JOIN <channel_id>
LEAVE <channel_id>
MSG <channel_id> <message>
// server send to client
JOIN <channel_id> <username>
LEAVE <channel_id> <username>
MSG <channel_id> <username> <message>
- So when a user connect to a server, you can randomly assign his username. You have an array to store all connection.
- Create array of channel. Each channel hold an array of user inside the channel.
- When client send
JOIN <channel_id>
to server. BroadcastJOIN <channel_id> <username>
to all the connection in that channel. - When client send
MSG <channel_id> <message>
to server. BroadcastMSG <channel_id> <username> <message>
to all connection in that channel. - so on and on ....
- 所以当用户连接到服务器时,你可以随机分配他的用户名。您有一个数组来存储所有连接。
- 创建通道数组。每个频道在频道内保存一个用户数组。
- 当客户端发送
JOIN <channel_id>
到服务器时。广播JOIN <channel_id> <username>
到该通道中的所有连接。 - 当客户端发送
MSG <channel_id> <message>
到服务器时。广播MSG <channel_id> <username> <message>
到该通道中的所有连接。 - 等等……
So basically, WebSocket provides a basic way of communicate, it is upto you to be creative to do thing.
所以基本上,WebSocket 提供了一种基本的通信方式,你可以发挥创造力来做事。
回答by Shakti Phartiyal
For private (room) chat systems you really have to develop your own logics. I would recommend you to use the following library:
对于私人(房间)聊天系统,您确实必须开发自己的逻辑。我建议您使用以下库:
Go through their documentation at http://socketo.me/docs/and start coding. If you get stuck then post your code and the community is here to help
在http://socketo.me/docs/浏览他们的文档并开始编码。如果您遇到困难,请发布您的代码,社区将为您提供帮助
回答by sumit
This is how I have done in Laravel, You need to install Predis , socket.io , ratchet and other dependencies . Please check https://laracasts.com/discuss/channels/general-discussion/step-by-step-guide-to-installing-socketio-and-broadcasting-events-with-laravel-51
这就是我在 Laravel 中所做的,您需要安装 Predis、socket.io、ratchet 和其他依赖项。请查看https://laracasts.com/discuss/channels/general-discussion/step-by-step-guide-to-installing-socketio-and-broadcasting-events-with-laravel-51
Make one custom artisan command to run a websockets on some port using ratchet
namespace App\Console\Commands; use Illuminate\Console\Command; use Ratchet\Server\IoServer; class webSockets extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'run:socket {port?}'; /** * The console command description. * * @var string */ protected $description = 'Run websockets for specified port'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $port = $this->argument('port'); $server = IoServer::factory( new ChatController(),$port $server->run(); }
}
制作一个自定义的 artisan 命令来使用棘轮在某个端口上运行 websockets
namespace App\Console\Commands; use Illuminate\Console\Command; use Ratchet\Server\IoServer; class webSockets extends Command { /** * The name and signature of the console command. * * @var string */ protected $signature = 'run:socket {port?}'; /** * The console command description. * * @var string */ protected $description = 'Run websockets for specified port'; /** * Create a new command instance. * * @return void */ public function __construct() { parent::__construct(); } /** * Execute the console command. * * @return mixed */ public function handle() { $port = $this->argument('port'); $server = IoServer::factory( new ChatController(),$port $server->run(); }
}
Your controller should be like below
您的控制器应该如下所示
namespace MyApp;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class ChatController implements MessageComponentInterface {
public function onOpen(ConnectionInterface $conn) {
}
public function onMessage(ConnectionInterface $from, $msg) {
//FIRE A BROADCAST EVENT HERE
event(new MessageBroadcast(
$message,
$datetime,
$user_id
)
);
}
public function onClose(ConnectionInterface $conn) {
}
public function onError(ConnectionInterface $conn, \Exception $e) {
}
}
THE BROADCAST CLASS SHOULD LOOK LIKE BELOW
广播类应该如下所示
namespace App\Events;
use App\Events\Event;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Queue\SerializesModels;
class MessageBroadcast extends Event implements ShouldBroadcast
{
use SerializesModels;
public $message,$datetime,$userid;
public function __construct($message,$datetime,$userid)
{
$this->message = $message;
$this->datetime = $datetime;
$this->userid = $userid;
}
public function broadcastOn()
{
return ['test-channel'.$this->user_id];
}
}
Javascript part to subscribe a channel
用于订阅频道的 Javascript 部分
<script src="{ { asset('js/socket.io.js') } }"></script>
<script>
//var socket = io('http://localhost:3000');
var socket = io('http://yourip:5000');
socket.on("test-channel1:App\Events\EventName", function(message){
// get user on console
console.log(message);
});
</script>
You need to run following command in backgroud
您需要在后台运行以下命令
1. php artisan run:socket <port_no>
2. Node yourjavascript.js