本文概述
- 要求
- 创建聊天
- 多次聊天
- 基本故障排除
传统上, 套接字是围绕其构建大多数实时聊天系统的解决方案, 它在客户端和服务器之间提供了双向通信通道。这意味着服务器可以将消息推送到客户端。每当你写聊天消息时, 其想法都是服务器将得到它并将其推送到所有其他连接的客户端。
注意:如标题中所述, 此实现是不可知的, 我们仅涵盖客户端的后端和基本功能。由你决定如何使用CSS或其他东西自定义它。
要求
- Ratchet Socketome软件包:Ratchet是一个松散耦合的PHP库, 为开发人员提供了工具, 可通过WebSockets在客户端和服务器之间创建实时双向应用程序。
composer require cboden/ratchet
或者, 你可以修改composer.json文件, 然后使用composer安装。
{"require": {"cboden/ratchet": "0.3.*"}}
- 支持套接字的浏览器。
创建聊天 为了开始简单的聊天, 我们将创建一个所有人都可以使用的开放空间(只要WebSocket定位到指定的URL)。
遵循的步骤
- 在包中的Sockets文件夹中创建Chat.php类。
- 在” 命令” 文件夹中创建一个symfony命令, 以通过命令控制台启动聊天。
- 在视图中使用Javascript处理套接字。
- 开始并测试你的聊天。
首先, 在捆绑软件的根文件夹中创建一个名为” 套接字” 的文件夹, 并在其上创建以下类(Chat.php)。
此类将处理所有连接, 消息等。稍后将在通过控制台进行初始化时使用它(请记住, 请根据你的软件包更改名称空间)。
<
?php// myapp\src\yourBundle\Sockets\Chat.php;
// Change the namespace according to your bundle, and that's all !namespace sandboxBundle\Sockets;
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
class Chat implements MessageComponentInterface {protected $clients;
public function __construct() {$this->
clients = new \SplObjectStorage;
}public function onOpen(ConnectionInterface $conn) {// Store the new connection to send messages to later$this->
clients->
attach($conn);
echo "New connection! ({$conn->
resourceId})\n";
}public function onMessage(ConnectionInterface $from, $msg) {$numRecv = count($this->
clients) - 1;
echo sprintf('Connection %d sending message "%s" to %d other connection%s' . "\n", $from->
resourceId, $msg, $numRecv, $numRecv == 1 ? '' : 's');
foreach ($this->
clients as $client) {if ($from !== $client) {// The sender is not the receiver, send to each client connected$client->
send($msg);
}}}public function onClose(ConnectionInterface $conn) {// The connection is closed, remove it, as we can no longer send it messages$this->
clients->
detach($conn);
echo "Connection {$conn->
resourceId} has disconnected\n";
}public function onError(ConnectionInterface $conn, \Exception $e) {echo "An error has occurred: {$e->
getMessage()}\n";
$conn->
close();
}}
现在我们在服务器端有了套接字处理程序, 我们需要创建代码来启动它。
创建命令以开始聊天
通常, 你应该保存代码以在php文件中启动它, 然后通过php file.php使用控制台。但是, 作为Symfony中的一个好习惯, 我们将在symfony命令中执行该代码, 这将使事情变得更轻松, 并且如果你想在控制器中执行命令或其他想要执行的疯狂事情, 你将能够执行。做。
要继续, 请在包的根文件夹中创建一个名为” Command” 的文件夹(如果尚不存在), 并在其上创建以下命令(SocketCommand.php)(你可以在此处阅读如何创建自定义symfony控制台命令)如果你想知道以下步骤的工作原理)。
不要忘记根据你的捆绑包更改名称空间。
<
?php// myapplication/src/sandboxBundle/Command/SocketCommand.php// Change the namespace according to your bundlenamespace sandboxBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
// Include ratchet libsuse Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
// Change the namespace according to your bundleuse sandboxBundle\Sockets\Chat;
class SocketCommand extends Command{protected function configure(){$this->
setName('sockets:start-chat')// the short description shown while running "php bin/console list"->
setHelp("Starts the chat socket demo")// the full command description shown when running the command with->
setDescription('Starts the chat socket demo');
}protected function execute(InputInterface $input, OutputInterface $output){$output->
writeln(['Chat socket', // A line'============', // Another line'Starting chat, open your browser.', // Empty line]);
$server = IoServer::factory(new HttpServer(new WsServer(new Chat())), 8080);
$server->
run();
}}
现在服务器端的所有内容都已准备就绪, 我们可以在命令行中使用php bin / console sockets:start-chat开始聊天, 但是我们需要在客户端处理套接字。
使用Javascript处理客户端套接字
要处理客户端, 只需在视图中添加以下代码即可。如你所见, 这非常简单, 它打开了Javascript WebSocket, 附加了最基本的事件, 并且从服务器发送JSON字符串到服务器, 并从服务器接收JSON字符串, 并在客户端进行处理。随时做得更好!
注意:取决于你要在其中放置客户端代码的位置。以下代码段可以在你的任何控制器的任何嫩枝视图或纯HTML响应中使用。切记更改套接字的URL(在本例中为ws:// sandbox:8080, 具体取决于你的测试域或本地主机)。
<
h1>
Public chat<
/h1>
<
ul id="chat-list">
<
/ul>
<
hr>
<
textarea id="form-message" placeholder="Your public message here">
<
/textarea>
<
input type="button" id="form-submit" value="http://www.srcmini.com/Send message"/>
<
script>
// This object will be sent everytime you submit a message in the sendMessage function.var clientInformation = {username: new Date().getTime().toString()// You can add more information in a static object};
// START SOCKET CONFIG/*** Note that you need to change the "sandbox" for the URL of your project. * According to the configuration in Sockets/Chat.php , change the port if you need to.* @type WebSocket*/var conn = new WebSocket('ws://sandbox:8080');
conn.onopen = function(e) {console.info("Connection established succesfully");
};
conn.onmessage = function(e) {var data = http://www.srcmini.com/JSON.parse(e.data);
Chat.appendMessage(data.username, data.message);
console.log(data);
};
conn.onerror = function(e){alert("Error: something went wrong with the socket.");
console.error(e);
};
// END SOCKET CONFIG/// Some code to add the messages to the list element and the message submit.document.getElementById("form-submit").addEventListener("click", function(){var msg = document.getElementById("form-message").value;
if(!msg){alert("Please send something on the chat");
}Chat.sendMessage(msg);
// Empty text areadocument.getElementById("form-message").valuehttp://www.srcmini.com/= "";
}, false);
// Mini API to send a message with the socket and append a message in a UL element.var Chat = {appendMessage: function(username, message){var from;
if(username == clientInformation.username){from = "me";
}else{from = clientInformation.username;
}// Append List Itemvar ul = document.getElementById("chat-list");
var li = document.createElement("li");
li.appendChild(document.createTextNode(from + " : "+ message));
ul.appendChild(li);
}, sendMessage: function(text){clientInformation.message = text;
// Send info as JSONconn.send(JSON.stringify(clientInformation));
// Add my own message to the listthis.appendMessage(clientInformation.username, clientInformation.message);
}};
<
/script>
你的一般聊天基本上已经准备就绪。
开始聊天并进行测试
要开始聊天, 请在控制台中使用先前创建的命令:
php bin/console sockets:start-chat
现在, 如果你只是复制粘贴了客户端代码(标记和javascript), 要对其进行测试以启动Google Chrome和Mozilla Firefox(不一定是那些, 而是2种不同的浏览器), 请导航至项目中的视图并查看魔术。
文章图片
你将能够在开始聊天的控制台中查看连接:
文章图片
恭喜你!你已经进行了简单的聊天, 可以自己进行自定义。
多次聊天 前面的聊天示例针对的是8080端口中域的根路径, 但是, 如果你的聊天不只针对一个聊天室, 则可以使用不同的处理程序创建不同的套接字路由。
在这种情况下, 我们将使用相同的Chat.php类, 但请注意, 初始化是不同的, 你的symfony命令需要更改。
在这种情况下, 而不是将ws:// sandbox:8080用作套接字路由, 现在我们将其更改为ws:// sandbox:8080 / chat。现在, 我们开始聊天的命令将是:
<
?php// myapplication/src/sandboxBundle/Command/SocketCommand.php// Change the namespace according to your bundlenamespace sandboxBundle\Command;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
// Ratchet libsuse Ratchet\App;
// Chat instanceuse sandboxBundle\Sockets\Chat;
class SocketCommand extends Command{protected function configure(){$this->
setName('sockets:start-chat')// the short description shown while running "php bin/console list"->
setHelp("Starts the chat socket demo")// the full command description shown when running the command with->
setDescription('Starts the chat socket demo');
}protected function execute(InputInterface $input, OutputInterface $output){$output->
writeln(['Chat socket', // A line'============', // Another line'Starting chat, open your browser.', // Empty line]);
// The domain of your app as first parameter// Note : if you got problems during the initialization, add as third parameter '0.0.0.0'// to prevent any error related to localhost :// $app = new \Ratchet\App('sandbox', 8080, '0.0.0.0');
// Domain as first parameter$app = new App('sandbox', 8080, '0.0.0.0');
// Add route to chat with the handler as second parameter$app->
route('/chat', new Chat);
// To add another routes, then you can use ://$app->
route('/america-chat', new AmericaChat);
//$app->
route('/europe-chat', new EuropeChat);
//$app->
route('/africa-chat', new AfricaChat);
//$app->
route('/asian-chat', new AsianChat);
// Run !$app->
run();
}}
如你所见, 只要你有更多的套接字处理程序类, 就可以轻松地向套接字端口添加更多路由。现在在客户端, websocket应该现在是:
var conn = new WebSocket('ws://sandbox:8080/chat');
基本故障排除 在本地工作, 但不能在远程或服务器中工作第一个示例有效, 但多条路线无效
这是一项安全功能!默认情况下, 棘轮绑定到127.0.0.1, 该绑定仅允许自身进行连接。推荐的方法是将Ratchet放在代理后面, 并且仅该代理(本地)将连接。
如果要打开Ratchet(不在代理后面), 则将App的第三个参数设置为” 0.0.0.0″ (如示例中所述)。
Ratchet Socketome的基本故障排除还包含其他问题, 稍后可能会发现。
【使用Symfony 3中的套接字使用PHP创建不可知的实时聊天】玩得开心 !
推荐阅读
- 如何自动在PHP中轻松生成带有logo的QR代码
- 如何在Windows中编辑和添加环境变量以方便命令行访问
- 如何在Symfony 3中创建和执行自定义控制台命令
- 如何使用C#Winforms和XAMPP连接到MySQL
- 在Symfony 3中使用FormType创建一个简单的联系表单
- 已解决–A project with an Output type of Class Library cannot be started directly
- android(如何调整对话框大小)
- Android(如何创建透明的对话框主题活动)
- Android自定义对话框大小[重复]