How to make a chat room script with PHP? [closed]

2019-01-22 10:13发布

问题:

Several visitors connect to http://site.com/chat.php

They each can write and send a text message to chat.php and it displays instantly on everyone's browser (http://site.com/chat.php)

Do I have to use a database? I mean, is AJAX or PHP buffer capabilities enough for such a chat room on sessions?

How can sessions of different users share data from each other?

Any idea or insights will be appreciated, thanks!

Edit: Thanks for the links. But what I want is the way to push data to a client browser. Is constantly refreshing client browser (AJAX or not) the only way? Also the challenge here is how different users, for example, 2, 1 on 1, share chat texts? How do you store them? And how do you synchronize the texts between the 2 clients? Not using a database preferably.

Edit 2: Actually YShout mentioned by Peter D does this job pretty well. It doesn't seem to keep refresh the browser. But I don't understand how it pushes new messages to existing user's window.

回答1:

there are (roughly) 3 options for creating a chat application:

sockets

use flash/java and sockets for the frontend and a socket-capable programming language for the backend. for the backend, i'd recommend java or python, because they are multithreading and NIO-capable. it's possible to do it with PHP (but php can't really do efficient multithreading and is generally not really suited for this). this is an option if you need high performance, and probably not what you're looking for.

use ajax and pull

in this case all clients are constantly (for example ever 2 seconds) polling if something new has happened. it feels strange because you only get responses at those intervals. additionally, it puts quite a strain on your server and bandwidth. you know an application uses this technique because the browser constantly refreshes. this is a suboptimal solution.

use ajax and push

this works with multipart-responses and has long running (php-) scripts in the backend. not the best solution, but most of the time it's better than pulling and it works and is used in several well known chat apps. this technique is sometimes called COMET.

my advise: if you need a chat app for production use, install an existing one. programming chat applications is not that easy.

if you just want to learn it, start with a simple ajax/pull app, then try to program one using ajax and push.

and yes, most probably you'll need a database, tough i successfully implemented a very simple ajax/pull solution that works with text files for fun (but i certainly wouldn't use it in production!).

it is (to my knowledge, but i'm pretty sure) not possible to create a chat app without a server-side backend (with just frontend javascript alone)!

UPDATE

if you want to know how the data pushing is done, look at the source here: http://wehrlos.strain.at/httpreq/client.html. async multipart is what you want :)

function asSendSyncMulti() {
    var httpReq = new XMLHttpRequest();

    showMessage( 'Sending Sync Multipart ' + (++this.reqCount)  );

    // Sync - wait until data arrives
    httpReq.multipart   = true;     
    httpReq.open( 'GET', 'server.php?multipart=true&c=' + (this.reqCount), false );
    httpReq.onload = showReq;
    httpReq.send( null );
}

function showReq( event ) {
    if ( event.target.readyState == 4 ) {
        showMessage( 'Data arrives: ' + event.target.responseText );
    }
    else {
        alert( 'an error occured: ' + event.target.readyState );
    }

}

showReq is called every time data arrives, not just once like in regular ajax-requests (i'm not using jquery or prototype here, so the code's a bit obese - this is really old :)).

here's the server side part:

<?php

    $c = $_GET[ 'c' ];

    header('Content-type: multipart/x-mixed-replace;boundary="rn9012"');

    sleep( 1 );

    print "--rn9012\n";
    print "Content-type: application/xml\n\n";
    print "\n";
    print "Multipart: First Part of Request " . $c . "\n";
    print "--rn9012\n";
    flush();

    sleep( 3 );

    print "Content-type: application/xml\n\n";
    print "\n";
    print "Multipart: Second Part of Request " . $c . "\n";
    print "--rn9012--\n";

?>

update2

regarding the database: if you've got a nothing-shared architecture like mod_php/cgi in the backend, you definitley need some kind of external storage like databases or textfiles. but: you could rely on memory by writing your own http server (possible with php, but i'd not recommend it for serious work). that's not really complicated, but probably a bit out of the scope of your question ^^

update3

i made a mistake! got everything mixed up, because it's been a long time i actually did something like that. here are the corrections:

  1. multipart responses only work with mozilla browsers and therefore are of limited use. COMET doesn't mean multipart-response.

  2. COMET means: traditional singlepart response, but held (with an infinite loop and sleep) until there is data available. so the browser has 1 request/response for every action (in the worst case), not one request every x seconds, even if nothing response-worthy happens.



回答2:

You mention wanting this to work without a DB, and without the client(s) polling the server for updates.

In theory you can do this by storing the "log" of chats in a text file on the server, and changing your page so that the user does a GET request on the chat.php page, but the PHP page never actually finishes sending back to the user. (e.g. the Response never completes)

You would need to send back some "no op" data to keep the connection going when there are no messages but in theory this would work.

The problem is, to accomplish the above is still a lot of work. You would need to do AJAX posts back to the server to submit new comments... the users' browser would be spinning the the whole time (unless you nest the chat log in an iframe - e.g. more work)... and this kind of setup would just be very hard to manage.

I'd suggest grabbing a free chat script from elsewhere (e.g. http://tinychat.com/) or if you want to roll your own (for fun/experience) then go ahead, but start with a DB and build a page that will push and pull messages from the server.

Finally if you are worried about "hammering" the server with AJAX requests... don't. Just build the chat, then if you find there are performance issues, return to StackOverflow with a question on how to optimize it so that hundreds of requests are not flooding the chat when there is no activity.



回答3:

While HTTP is not made for easy pushing, you can emulate a push connection by having the PHP script never terminate and the JavaScript result be watched carefully.

Essentially you're simulating a stream reader.



回答4:

If you would like new users to load a history of the chat that occurred before they entered the room, a DB or other storage is required. Unless you are trying to create a chat for learning, there are too many out there to use for free to bother.

http://tinychat.com is another simple chat site.

AJAX works fine. I have created a simple page for one of my sites. But I find that chat doesn't get used as often as you would think.

Sharing data gets a little more complicated and would be easier to accomplish by hosting an IRC server and allowing users to use IRC clients which have data exchange capability. Although nothing is stopping you from having one user upload to the site, then others download. Person to person would be difficult with using a web interface, because the users are not connected in any way with each other.



回答5:

and it displays instantly on everyone's browser

With php / JS you cannot push data from server to clients. So your clients need to ask for data from the server. And that's what scunliffe has described in his post.



回答6:

You can do this entirely with HTML and Javascript using a service like PubNub. You wouldn't need a database as you could use something like the history api to populate the last x chat messages.

Here is a quick tutorial on building a chat app with PubNub.

Real-time Chat Apps in 10 Lines of Code

Enter Chat and press enter
<div><input id=input placeholder=you-chat-here /></div>

Chat Output
<div id=box></div>

<script src=http://cdn.pubnub.com/pubnub.min.js></script>
<script>(function(){
var box = PUBNUB.$('box'), input = PUBNUB.$('input'), channel = 'chat';
PUBNUB.subscribe({
    channel  : channel,
    callback : function(text) { box.innerHTML = (''+text).replace( /[<>]/g, '' ) + '<br>' + box.innerHTML }
});
PUBNUB.bind( 'keyup', input, function(e) {
    (e.keyCode || e.charCode) === 13 && PUBNUB.publish({
        channel : channel, message : input.value, x : (input.value='')
    })
} )
})()</script>


标签: php chatroom