PHP SOCKE实现聊天系统

费话不多讲,具体看代码

1.服务端实现

class Ws{

    private $host = ‘127.0.0.1‘;
    private $port = 8080;
    private $maxuser = 10;
    private $socket;
    public $accept = [];
    private $isHand = [];
    private $cycle = [];
    public function __construct($host,$port,$maxuser)
    {
        $this->host = $host;
        $this->port = $port;
        $this->maxuser = $maxuser;
    }

    public  function start()
    {
        // 创建一个Socket
        $this->socket = socket_create(AF_INET,SOCK_STREAM,SOL_TCP);
         //允许使用本地地址
        socket_set_option($this->socket,SOL_SOCKET,SO_REUSEADDR,TRUE);
        // 绑定地址和端口
        socket_bind($this->socket,$this->host,$this->port);
        //侦听
        socket_listen($this->socket,$this->maxuser);
        while(True){
            $this->cycle = $this->accept;
            $this->cycle[] = $this->socket;
            //阻塞用,有新连接时才会结束
            socket_select($this->cycle, $write, $except, null);
            //轮询
            foreach($this->cycle as $key =>$v){

                if($v === $this->socket){
                    //当接受一个Socket不成功时,继续下一个
                    if(($accept = socket_accept($v))<0){
                        continue;
                    }
                    //添加到循环池
                    $this->add_accept($accept);
                    continue;
                }

                // 获得当前连接健值
                $index = array_search($v,$this->accept);

                if($index === null){
                    continue;
                }

                // 接受客户端数据
                if( [email protected]_recv($v,$data,1024,0) || !$data){

                    $this->close($v);
                    continue;
                }

                // 握手并发送用户连接数
                if(!$this->isHand[$index]){
                    $this->upgrade($v,$data,$index);
                    call_user_func_array(‘user_add_callback‘,array($this));
                    continue;
                }
                $data = $this->decode($data);
                // 发送数据
                call_user_func_array(‘send_callback‘, array($data, $index, $this));
            }
            sleep(1);
        }    

    }

回调

  function send_callback($data, $index, $ws) {
    $data = json_encode(array(
                        ‘text‘ => $data,
                        ‘user‘ => $index,
                        ));
    send_to_all($data, ‘text‘, $ws);
}

function send_to_all($data, $type, $ws){
    $res = array(
            ‘msg‘ => $data,
            ‘type‘ => $type,
            );
    $res = json_encode($res);
    $res = $ws->frame($res);
    print_r($ws->accept);
    foreach ($ws->accept as $key => $value) {
        socket_write($value, $res, strlen($res));
    }
}

function close_callback($ws) {
    $data = count($ws->accept);
    send_to_all($data, ‘num‘, $ws);
}

function user_add_callback($ws) {
    $data = count($ws->accept);
     send_to_all($data, ‘num‘, $ws);
}

客户端实现

<!DOCTYPE html>
<html dir="ltr" lang="zh" xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>websocket聊天室</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">

</head>
<body>
<div class="container">
    <p>在线人数<span id="userNum"></span></p>
    <textarea id="message" rows="10"></textarea>
    <div class="send">
        <p><textarea id="input" placeholder="请输入要发送的内容"></textarea></p>
        <p><button type="button" class="btn btn-primary" id="sub">发送</button></p>
    </div>
</div>
<script type="text/javascript">
(function(){
    var $ = function(id){return document.getElementById(id) || null;}
    var wsServer = ‘ws://127.0.0.1:8080‘;
    var ws = new WebSocket(wsServer);
    var isConnect = false;
    ws.onopen = function (evt) { onOpen(evt) };
    ws.onclose = function (evt) { onClose(evt) };
    ws.onmessage = function (evt) { onMessage(evt) };
    ws.onerror = function (evt) { onError(evt) };
    function onOpen(evt) {
        console.log("连接服务器成功");
        isConnect = true;
    }
    function onClose(evt) {
        //console.log("Disconnected");
    }
    function onMessage(evt) {
        var data = JSON.parse(evt.data);
        switch (data.type) {
            case ‘text‘:
                addMsg(data.msg);
                break;
            case ‘num‘ :
                updataUserNum(data.msg);
                break;
        }

        console.log(‘Retrieved data from server: ‘ + evt.data);
    }
    function onError(evt) {
        //console.log(‘Error occured: ‘ + evt.data);
    }
    function sendMsg() {
        if(isConnect){
            ws.send($(‘input‘).value);
            $(‘input‘).value = ‘‘;
        }
    }
    function addMsg(msg) {
        msg = JSON.parse(msg);
        var text = ‘用户‘ + msg.user + ‘说:\n‘ + msg.text + ‘\n‘;
        $(‘message‘).value += text;
        $(‘message‘).scrollTop = $(‘message‘).scrollHeight;
    }
    function updataUserNum(msg) {
        $(‘userNum‘).innerText = msg;
    }
    $(‘sub‘).addEventListener(‘click‘,sendMsg,false);
})();
</script>
</body>
</html>
时间: 2024-10-11 02:56:06

PHP SOCKE实现聊天系统的相关文章

简易版聊天系统实现 Socket VS NIO两种实现方式

说是简单聊天系统,压根不能算是一个系统,顶多算个雏形.本文重点不在聊天系统设计和实现上,而是通过实现类似效果,展示下NIO 和Socket两种编程方式的差异性.说是Socket与NIO的编程方式,不太严谨,因为NIO的底层也是通过Socket实现的,但又想不出非常好的题目,就这样吧. 主要内容 Socket方式实现简易聊天效果 NIO方式实现简易聊天效果 两种方式的性能对比 前言 预期效果,是客户端之间进行"广播"式聊天,类似于QQ群聊天.希望以后有机会,以此简易版为基础,不断演进,演

Java网络编程基础(六)— 基于TCP的NIO简单聊天系统

在Java网络编程基础(四)中提到了基于Socket的TCP/IP简单聊天系统实现了一个多客户端之间护法消息的简单聊天系统.其服务端采用了多线程来处理多个客户端的消息发送,并转发给目的用户.但是由于它是基于Socket的,因此是阻塞的. 本节我们将通过SocketChannel和ServerSocketChannel来实现同样的功能. 1.客户端输入消息的格式 username:msg    username表示要发送的的用户名,msg为发送内容,以冒号分割 2.实现思路 实现思路与Java网络

使用Unity自带的NetWorkView实现简单的聊天系统

众所周知,在游戏中,我们经常会简单带聊天系统.一般,我们常见的有公会聊天,也就是大家熟知的QQ群聊,还有就是私聊,相信大家都懂得.好了, 废话不多扯了,我们开工. 首先,我们来写服务器端的. 老规矩,我们先搭建基本的UI.我们这里仍然使用NGUI.服务器端,我们主要负责显示客户端接入情况和收集全部消息,然后同步给每个客户端. 首先,我们创建一个Sprite,重命名为BackGround,然后为其选择图集和精灵,将其颜色调整为黑色,大小为整个UIRoot.然后,我们创建一个Label,重命名为Ti

resin WED服务器初用遇到的问题和解决方法 java.lang.RuntimeException: java.net.SocketException: Unrecognized Windows Socke ts error: 0: JVM_Bind

开启resin 服务器以后提示如下:(控制台不断的循环循环打印如下错误提示) java.lang.RuntimeException: java.net.SocketException: Unrecognized Windows Sockets error: 0: JVM_Bind at com.caucho.server.cluster.Server.start(Server.java:1191) at com.caucho.server.cluster.Cluster.startServer(

基于Netty的聊天系统(一)通讯原理篇

今天周六,正好顺便把聊天系统的通讯原理写一下,本来是用XMPP+Openfire做了一个聊天,但是在做群聊那块需要去写插件来主动向表里变去写数据,因为openfire外国人写的,最初设计的群聊是会议室那种形式,和我们现在这种QQ群聊还是有差别的,改造起来比较麻烦,需要去通都源码等等,openfire是基于mina来写的,mina和netty又出自同一作者之手,那么我们就基于netty来写一个吧,首先我们来谈一谈通讯的原理 1:通讯原理 首先比方说A和B两个人要进行聊天(这里我们先讨论一对一这种聊

网络编程基础【day08】:socke编程入门

本节内容 OSI七层模型 socke通信介绍 简单socket实例 通过socket实现简单ssh客户端 OSI七层模型 socke通信介绍 一.概述 socket通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,应用程序通常通过"套接字"向网络发出请求或者应答网络请求. socket起源于Unix,而Unix/Linux基本哲学之一就是"一切皆文件",对于文件用[打开][读写][关闭]模式来操作.socket就是该模式的一个实现

java实现聊天系统项目笔记

JavaSE学完以后,用java实现的聊天室融合了很多java知识. 比如GUI简单的图形界面,集合,IO,多线程,socket,监听等. 那么这个聊天系统是如何实现的呢? 首先我们要有界面.如图所示. 这仅仅是一个简单的Frame窗口界面. 首先package : 包入境,相当于这个类文件的绝对路径,与别人重复几率减小 import   : 导入包/类的意思.当要想调用某个包中的类的方法,就要用到import extends : ChatClient01继承Frame,相当于,继承了父类Fra

Java-在线聊天系统-非线程

一.概述 1.目标:建立基于tcp协议的聊天系统 2.思路:用java socket编程 二.代码 1.ChatServer.java import java.io.DataInputStream; import java.io.EOFException; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.UnknownHostException; p

基于Netty的聊天系统(三)协议定制----消息篇

今天我们继续来讨论协议,今天基本就把一对一聊天的协议定制完毕了,上一篇我们讲述了登录的过程,那么登录完毕就是聊天了,首先我们还是以A和B为例子,A发送消息给B,那么这条消息的的协议如下 发送消息协议: {"id":"xxxx","#":"msg","text":"内容","to":"接收用户ID","type":0,"