while(true){
      $changed = $this->sockets;
      $write=NULL;
      $except=NULL;
      socket_select($changed,$write,$except,NULL);
      foreach($changed as $socket){       
        if($socket==$this->master){         
          $client=socket_accept($this->master);
          if($client<0){ $this->log("socket_accept() failed"); continue; }
          else{ $this->connect($client); }
        }
        else{
          /*if(1=1){
          $user = $this->getuserbysocket($socket);
          if(!$user->handshake){ $this->dohandshake($user,$buffer);}
          $this->process($user,$this->unwrap($buffer));
          }*/
          $bytes = @socket_recv($socket,$buffer,2048,0);
          if($bytes==0){ $this->disconnect($socket); }
          else{
            $user = $this->getuserbysocket($socket);
            if(!$user->handshake){ $this->dohandshake($user,$buffer);}
            else{ $this->process($user,$this->unwrap($buffer));}
          }
        }
      }
    }
上面的代码,是phpwebsocket的一个示例,while是在构造函数里面的。原来的示例,是客户端连接后,服务端一直监听,如果有消息,就处理后返回。现在我想改成,当某种条件成立时,服务端主动向客户端发信息。我把$bytes=@socket  。。  $this->process($user,$this->unwrap($buffer));} 这段代码换成注释部分,可一直连接不上。希望高手们帮帮忙

解决方案 »

  1.   

    本帖最后由 xuzuning 于 2013-04-06 09:16:29 编辑
      

  2.   

    连接不上 是什么意思?
    socket服务器端程序不同,客户端也要不同的的
    一般情况下是client pull,你要实现server push,客户端要写成主动接收才行(一般情况下只是被动接收,先发后收)
      

  3.   

    今天又作了一些修改。现在是客户端和服务端握手后,服务端可以主动发信息给客户端,但这样又有一个问题。服务端是否要发信息给客户端,我是用WHILE处理的,当某种条件成立,我就发给客户端。可是这样WHILE下去,其他客户端就连不上了,甚至连第一个连上的客户端断开,服务端也不知道。这样的情况,是不是要用多线程。是的话,要怎么做,PHP没多线程,怎么去模拟多线程,求给个例子。
    我的思路是这样的,服务端还是一直保持不变,但服务器上多执行一个程序(一直WHILE的),但条件成立时,就向服务端发信息,服务端收到后,就处理完广播给其他所有人。这样子得开两个程序,而且还有很多麻烦的地方,比如服务端收到信息,还要判断是不是一直WHILE的那个客户端等等。是否有其他更好的思路?
      

  4.   

    我想用WEBSOCKET来代替长轮询,但我不知道服务端要怎样监听端口和接收数据的同时,自身也能用WHILE判断某种条件是否成立,成立要主动向客户端发数据
      

  5.   

    现在我改后的代码是这样的
    $bytes = @socket_recv($socket,$buffer,2048,0);
              if($bytes==0){ $this->disconnect($socket); }
              else{
                $user = $this->getuserbysocket($socket);
                if(!$user->handshake){ $this->dohandshake($user,$buffer);while(true){if(条件是否成立){主动向客户端发数据}sleep(3);}}
                else{ $this->process($user,$this->unwrap($buffer));}
    这样子,条件成立的时候,服务端可以向客户端发信息。只是其他人连不上,断开的服务端也不知道
      

  6.   

    估计是想实现楼上说的功能PHP socket服务端 楼主难不成是通过HTTP请求过来 这个脚本一直在WHILE?  SOCKET 和长轮训实现起来是有差别的
    你想实现的服务是可以的不过要用命令行启动类似一个服务  客户端通过IP和端口来访问  服务端脚本是要不断监听是否有客户端连接进来 或者是要推送信息到客户端
      

  7.   

    没尝试过这方面,一下子说不出什么
    单线程是可以的,其他语言也有单线程的实例,问题应该出在其他方面
    单线程一般要用异步,select就是异步,但我不太熟悉服务器端的编程(暂时还没接触)
    不能一直占用,完成一个发送或接收就要交出控制权,异步机制一般不需要while的,while只用来完成一个send或者recv,异步是通过判断可读或可写触发读、写(收发)要注意
    $bytes = @socket_recv($socket,$buffer,2048,0);
              if($bytes==0){ $this->disconnect($socket); }
    这个逻辑是没有接收就断开了(长连接不应随便断开),socket有很多逻辑要认真考虑的,你目前代码还没涉及socket err的情况,那里的逻辑更多更复杂;现在光看socket文档所说的错误号就有几十个,越写越背脊发凉……客户端我还能说点具体的,最近有在写,服务器端抱歉我只能说理论知识
      

  8.   

    先撇开 php 不说,我们先来复习一下 socket 通讯是如何进行的
    socket 是实现 tcp/ip 协议的工具包,他集成了 tcp、udp 通讯的所有功能
    其中 tcp 是点对点通讯,udp 是广播通讯
    在无职守的通讯网络中
    主叫方通过 udp 将目标请求广播出去并监听应答端口
    被叫方(如果在线)鉴别到是呼叫自己时,通过 udp 或 tcp 发出回应
    主叫方收到回应后,协同被叫方创建 tcp 通讯通道。然后进行双向点对点通讯
    在有职守的通讯网络中
    主叫方向职守(服务器)通过 tcp 发送请求
    职守向被叫方通过 tcp 转发呼叫
    被叫方(如果在线)收到呼叫后,通过 tcp 发出回应
    主叫方收到回应后
    1、可以继续通过职守进行与被叫方的通讯
    2、可以直接建立与被叫方的双向通讯于是,只要你的程序能够满足实现通讯所需的条件,就能正常工作
      

  9.   

    那如果不能支持多线程,又怎么实现通讯。就像其他语言,在学SOCKET和多线程的时候,总会看到这样的示例。客户端发给服务端,服务端处理完回应客户端,客户端又接收完回应服务端。但是如果客户端发送完之后,想在服务端没回之前又发送一次呢,这时候不就需要多线程来解决了。但网上找了一些资料,好像说有个pcntl的fork可以实现多线程,但那个模块只有UNIX能用。我是用WINDOWS的,得怎么处理多线程的问题
      

  10.   

    可以同时监听多个客户端,也可以同时处理多个客户端发送来的消息。我现在遇到的问题是,想同时做多一个WHILE循环,比如某个文件的内容发生变化,我就去通知一些客户端。
      

  11.   

    你到底是要问socket还是多线程?说面说的只是打个比方 当然可能不太贴切
    如果你要问的是socket 我觉得你还是别纠结了 去网上找个DEMO很多的 看下别人的代码你应该就能明白了 如果看不懂别人的代码 说明你还有好多需要修炼 建议从基础开始如果是多线程 php不支持多线程 你具体要实现个啥?
      

  12.   

    给你个例子吧 
    http://code.google.com/p/phpwebsocket/ 
      

  13.   

    自己跑了下 发现程序确实不能很好工作 看了你上面的问题和答复 感觉你也应该是个有些基础的 源码现在不能用不代表方法行不通 你调试下错误就知道他的错误和你所需要的东西根本就不冲突你是想要学会socket 还是只想让人帮你做个socket的东西能用 我理解可能一个拿过来就直接能用的研究起来会比较好  但是作为一个提问者 求知 难不成你以为这里人都会像学校老师一样一口一口去喂你么   方法别人都已经告诉你了  你说这个不好用 可以去网上找个更好用的  在我看来这份源码足够你了解这部分 如果是我我会看看别人的源码思路 然后自己比照着写一个  来验证自己心中的疑惑  如果这个源码和设想的完全一样 你当时调试通了 知道咋回事 不出半个月 如果你不搞这块技术 我可以保证你会忘得光光的   即使你觉得自己了解了 让你脱开网络和DEMO也很难写出一个能用的东西   学习是要讲究方法的   
      

  14.   

    google那个phpwebsocket,我已经改成我想要的了,两天前的事了。只是有点不明白,如果我想用PHP实现类似多线程的东西,得怎么做。如果你这方面熟悉,那麻烦你帮我写个小的DEMO就行,服务端和客户端能保持通讯的同时,服务端要监视一个文件,如果文件内容改变了,就去通知客户端。我现在是用另一种方式实现我的需求,但扩展性太差,你写个DEMO给我,我就可以改写自己的程序了。当然前提是你能抽出时间来,谢谢了。