Welcome to a tutorial on how to create a PHP live chat application with WebSockets. Looking to add live chat features to your website or portal?
The simplified mechanics of a PHP WebSockets live chat application are:
- Create a command-line PHP script that will run and manage a WebSocket chat server.
- Use the Javascript WebSocket API to connect clients to the PHP chat server.
- When a client sends a chat message to the server, it will forward the message to all the other connected clients.
But just how exactly is it done? Let us walk through an example in this guide – Read on!
ⓘ I have included a zip file with all the source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
TABLE OF CONTENTS
DOWNLOAD & NOTES
First, here is the download link to the source code as promised.
QUICK NOTES
For you guys who just want to use this as a “plugin”:
- A copy of PHP Ratchet is required, but not included in the zip file. Use Composer to pull the latest version –
composer require cboden/ratchet
. - Run
chat-server.php
in the command line, this will deploy the chat server at port 8080. Changesection D
if you want to specify another port. - Access
chat-client.html
in the web browser. It is recommended to change thehost
insection B
ofchat-client.js
to your own domain/IP address.
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
VIDEO SETUP GUIDE
PHP LIVE CHAT SERVER
All right, let us now get into more details of the chat server, for those who want to customize it.
PHP WEBSOCKET LIVE CHAT CLASS
<?php
// (A) COMMAND LINE ONLY!
if (isset($_SERVER["REMOTE_ADDR"]) || isset($_SERVER["HTTP_USER_AGENT"]) || !isset($_SERVER["argv"])) {
exit("Please run this in the command line");
}
// (B) LOAD RATCHET
require "vendor/autoload.php";
use Ratchet\MessageComponentInterface;
use Ratchet\ConnectionInterface;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
// (C) CHAT CLASS
class Chat implements MessageComponentInterface {
// (C1) PROPERTIES
private $debug = true; // Debug mode
protected $clients; // Connected clients
// (C2) CONSTRUCTOR - INIT LIST OF CLIENTS
public function __construct () {
$this->clients = new \SplObjectStorage;
if ($this->debug) { echo "Chat server started.\r\n"; }
}
// (C3) ON CLIENT CONNECT - STORE INTO $THIS->CLIENTS
public function onOpen (ConnectionInterface $conn) {
$this->clients->attach($conn);
if ($this->debug) { echo "Client connected: {$conn->resourceId}\r\n"; }
}
// (C4) ON CLIENT DISCONNECT - REMOVE FROM $THIS->CLIENTS
public function onClose (ConnectionInterface $conn) {
$this->clients->detach($conn);
if ($this->debug) { echo "Client disconnected: {$conn->resourceId}\r\n"; }
}
// (C5) ON ERROR
public function onError (ConnectionInterface $conn, \Exception $e) {
$conn->close();
if ($this->debug) { echo "Client error: {$conn->resourceId} | {$e->getMessage()}\r\n"; }
}
// (C6) ON RECEIVING MESSAGE FROM CLIENT - SEND TO EVERYONE
public function onMessage (ConnectionInterface $from, $msg) {
if ($this->debug) { echo "Received message from {$from->resourceId}: {$msg}\r\n"; }
foreach ($this->clients as $client) { $client->send($msg); }
}
}
// (D) WEBSOCKET SERVER START!
$server = IoServer::factory(new HttpServer(new WsServer(new Chat())), 8080); // @CHANGE if not port 8080
$server->run();
Not going to explain this library line-by-line, but in essence:
- Just a “safety check” to make sure the script is run from the command line.
- Load and use the Ratchet library.
- The mechanics of the chat application, basically:
- We store all clients into
$this->clients
when they connect to the WebSocket server. - Captain Obvious, remove the clients from
$this->clients
when they disconnect. - On receiving a message from any client, we loop through
$this->clients
and forward the message to everyone.
- We store all clients into
- Start running the server.
Yep. That’s all for the “complicated chat server”.
LIVE CHAT CLIENT
Next, we shall walk through the chat client – Which is built using the Javascript WebSocket API.
HTML CHAT PAGE
<div id="chat-wrap">
<!-- (A) CHAT MESSAGES -->
<div id="chat-messages"></div>
<!-- (B) SET NAME -->
<form id="chat-name" onsubmit="return chat.start()">
<input type="text" id="chat-name-set" placeholder="What is your name?" value="John Doe" required/>
<input type="submit" id="chat-name-go" value="Start"/>
</form>
<!-- (C) SEND MESSAGE -->
<form id="chat-send" onsubmit="return chat.send()">
<input type="text" id="chat-send-text" placeholder="Enter message" required/>
<input type="submit" id="chat-send-go" value="Send"/>
</form>
</div>
This should be straightforward, there are 3 parts to the HTML chat interface:
<div id="chat-messages">
is where we show all the chat messages.<form id="chat-name">
is where we ask the user for a name before launching the chat.- Lastly,
<form id="chat-send">
is the “send a message” box. This is hidden at first, will only show after the user enters a name and successfully connects to the WebSocket server.
LIVE CHAT JAVASCRIPT
var chat = {
// (A) HELPER FUNCTION - SWAP BETWEEN SET NAME/SEND MESSAGE
swapform : (direction) => {
// (A1) SHOW SEND MESSAGE FORM
if (direction) {
document.getElementById("chat-name").style.display = "none";
document.getElementById("chat-send").style.display = "grid";
}
// (A2) SHOW SET NAME FORM
else {
document.getElementById("chat-send").style.display = "none";
document.getElementById("chat-name").style.display = "grid";
document.getElementById("chat-name-go").disabled = false;
}
},
// (B) START CHAT
host : "ws://localhost:8080/", // @CHANGE to your own!
name : "", // Current user name
socket : null, // Websocket object
htmltxt : null, // HTML send text field
start : () => {
// (B1) CREATE WEB SOCKET
document.getElementById("chat-name-go").disabled = true;
if (chat.htmltxt==null) { chat.htmltxt = document.getElementById("chat-send-text"); }
chat.socket = new WebSocket(chat.host);
// (B2) READY - CONNECTED TO SERVER
chat.socket.onopen = (e) => {
chat.name = document.getElementById("chat-name-set").value;
chat.swapform(1);
};
// (B3) ON CONNECTION CLOSE
chat.socket.onclose = (e) => { chat.swapform(0); };
// (B4) ON RECEIVING DATA FROM SEREVER - UPDATE CHAT MESsAGES
chat.socket.onmessage = (e) => {
let msg = JSON.parse(e.data),
row = document.createElement("div");
row.innerHTML = `<div class="ch-name">${msg.n}</div><div class="ch-msg">${msg.m}</div>`;
row.className = "ch-row";
document.getElementById("chat-messages").appendChild(row);
};
// (B5) ON ERROR
chat.socket.onerror = (e) => {
chat.swapform(0);
console.log(e);
alert(`Failed to connect to ${chat.host}`);
};
return false;
},
// (C) SEND MESSAGE
send : () => {
let message = JSON.stringify({
n: chat.name,
m: chat.htmltxt.value
});
chat.htmltxt.value = "";
chat.socket.send(message);
return false;
}
};
This is yet another “massive script”, but keep calm and look carefully – The var chat
object literally contains all the mechanics to run the live chat.
- Remember that the “send message” docket will show after the user enters a name?
swapform()
is the helper function that does the switcheroo thing. - A whole bunch of stuff that happens after the user enters the name and clicks on “start”. Long story short,
start()
creates a WebSocket object, connects to the server, and handles the HTML chat update on receiving messages from the server. - Self-explanatory,
send()
will send a chat message to the server.
USEFUL BITS & LINKS
That’s all for this guide, and here is a small section on some extras that may be useful to you.
COMPATIBILITY CHECKS
- Arrow Functions – CanIUse
- Template Literals – CanIUse
- WebSocket API – CanIUse
Works across all modern browsers.
LINKS & REFERENCES
If you want to learn more about sockets, here are the official links:
- Sockets – PHP
- WebSocket API – MDN
- Ratchet Documentation
THE END
Thank you for reading, and we have come to the end of this guide. That took quite a lot of research, work, and I can easily see why some people are charging money for it… But I hope that this has helped you in your project, and if you want to share anything, please feel free to comment below. Good luck and happy coding!
Server is running
path is localhost/php-chat/chat-server.php but getting this error :: Please run this in the command line
can you help me pleas :
“Fools despise wisdom and instruction” – Proverbs 1:7
Here, we have another specimen of humanity’s finest “big brain genius”. Who, decided the best course of action is to skip a 5 minutes tutorial and wonder why things don’t work for days. Perhaps, it is to demonstrate their unrivaled talent of bringing suffering upon themselves.
Sadly, this less talented human cannot supersede such a superior level of intelligence. Please help yourself. The step-by-step instructions and an entire setup video guide are right above. 🙄
As humorous as the post is and likelyhood that they didnt read anything, after having read YOUR code, it’s VERY possible that it would give this error even if they did run it from the command line. So, I would probably hold off on any “less than talented human” claims considering you seem to suffer from the same issue when you search for “user-agent” when calling from the command line. In quite a few hosting environments, those will actually be set with “curl/X.x”. You should not be checking for a user agent when calling from command line. That is absurd. However, the check for argv is appropriate and it’s actually the ONLY var you need to be checking for in a command line context. The other 2 you have are complete garbage.
Thanks for reporting the possible hiccup to the less talented humans. Will look for better ways to detect the command line in the next update.
P.S. None of the 500 tutorials on this site is perfect, it is always a pleasure to see geniuses react. Bless the ones who shed light graciously. While the few who love to flash their “big dong of stellar self-righteousness” are unmannerly, they are entertaining and never get old nonetheless. Cheers! 😆
https://code-boxx.com/faq/#badatti
hi,
i am trying using this chat on live server but i am not able to connection is getting failed this is my url can you please help with this =URL REMOVED=
https://code-boxx.com/faq/#help
https://code-boxx.com/faq/#notwork