GVKun编程网logo

PHP+swoole实现简单多人在线聊天群发(php即时多人聊天)

25

对于PHP+swoole实现简单多人在线聊天群发感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解php即时多人聊天,并且为您提供关于java实现多人在线聊天室、Java通过Socket实现简

对于PHP+swoole实现简单多人在线聊天群发感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解php即时多人聊天,并且为您提供关于java实现多人在线聊天室、Java通过Socket实现简单多人聊天室、PHP + Swoole 简单聊天室、php swoole实现简单redis连接池的宝贵知识。

本文目录一览:

PHP+swoole实现简单多人在线聊天群发(php即时多人聊天)

PHP+swoole实现简单多人在线聊天群发(php即时多人聊天)

由于本文的能力有限,有好多聊天逻辑的细节没有实现,只实现了群发,具体代码如下所示:

php代码:

$serv = new swoole_websocket_server("127.0.0.1",3999);
//服务的基本设置
$serv->set(array(
''worker_num'' => 2,
''reactor_num''=>8,
''task_worker_num''=>1,
''dispatch_mode'' => 2,
''debug_mode''=> 1,
''daemonize'' => true,
''log_file'' => __DIR__.''/log/webs_swoole.log'',
''heartbeat_check_interval'' => 60,
''heartbeat_idle_time'' => 600,
));
$serv->on(''connect'', function ($serv,$fd){
// echo "client:$fd Connect.".PHP_EOL;
});
//测试receive
$serv->on("receive",function(swoole_server $serv,$fd,$from_id,$data){
// echo "receive#{$from_id}: receive $data ".PHP_EOL;
});
$serv->on(''open'', function($server, $req) {
// echo "server#{$server->worker_pid}: handshake success with fd#{$req->fd}".PHP_EOL;;
// echo PHP_EOL;
});
$serv->on(''message'',function($server,$frame) {
// echo "message: ".$frame->data.PHP_EOL;
$msg=json_decode($frame->data,true);
switch ($msg[''type'']){
case ''login'':
$server->push($frame->fd,"欢迎欢迎~");
break;
default:
break;
}
$msg[''fd'']=$frame->fd;
$server->task($msg);
});
$serv->on("workerstart",function($server,$workerid){
// echo "workerstart: ".$workerid.PHP_EOL;
// echo PHP_EOL;
});
$serv->on("task","on_task");
$serv->on("finish",function($serv,$task_id,$data){
return ;
});
$serv->on(''close'', function($server,$fd,$from_id) {
// echo "connection close: ".$fd.PHP_EOL;
// echo PHP_EOL;
});
$serv->start();
function on_task($serv,$task_id,$from_id,$data) {
switch ($data[''type'']){
case ''login'':
$send_msg="说:我来了~";
break;
default:
$send_msg="说:{$data[''msg''][''speak'']}";
break;
}
foreach ($serv->connections as $conn){
if ($conn!=$data[''fd'']){
if (strpos($data[''msg''][''name''],"游客")===0){
$name=$data[''msg''][''name'']."_".$data[''fd''];
}else{
$name=$data[''msg''][''name''];
}
}else{
$name="我";
}
$serv->push($conn,$name.$send_msg);
}
return;
}
function on_finish($serv,$task_id,$data){
return true;
}

前端代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>WebSocket测试</title> 
<script language="javascript"type="text/javascript" src="jquery-1.12.0.min.js"> 
</script>
</head>
<body>
<h2>WebSocket Test</h2> 
昵称:<input type="text" id="name" size="5" value="游客"/> <input type="text" id="content"> 
<button onclick="speak_to_all()">发送</button>
<br/><br/>
<textarea id="message"rows="10" cols="50"></textarea> 
<div id="output"></div>
</body> 
<script language="javascript"type="text/javascript"> 
var wsUri ="ws://127.0.0.1:3999/"; 
var output; 
function init() { 
output = document.getElementById("output"); 
testWebSocket();
}
function testWebSocket() { 
websocket = new WebSocket(wsUri); 
websocket.onopen = function(evt) { 
onOpen(evt) 
}; 
websocket.onclose = function(evt) { 
onClose(evt) 
}; 
websocket.onmessage = function(evt) { 
onMessage(evt) 
}; 
websocket.onerror = function(evt) { 
onError(evt) 
}; 
}
function get_speak_msg(){
var name=document.getElementById("name").value;
var speak=document.getElementById("content").value;
var json_msg=''{"name":"''+name+''","speak":\"''+speak+''"}'';
return json_msg;
}
function pack_msg(type,msg){
return ''{"type":"''+type+''","msg":''+msg+''}'';
}
function onOpen(evt) {
append_speak("已经联通服务器.........");
speak_msg=get_speak_msg();
send_msg=pack_msg("login",speak_msg);
doSend(send_msg);
}
function onClose(evt) { 
append_speak("俺老孙去也!");
} 
function onMessage(evt) {
append_speak(evt.data);
}
function onError(evt) {
alert(evt.data);
}
function doSend(message) { 
websocket.send(message);
}
function append_speak(new_msg){
document.getElementById("message").value=document.getElementById("message").value+new_msg+"\n";
document.getElementById(''message'').scrollTop = document.getElementById(''message'').scrollHeight;
}
function speak_to_all(){
send_msg=pack_msg("speak",get_speak_msg());
if(document.getElementById("content").value==""){
return;
}
doSend(send_msg);
document.getElementById("content").value="";
}
init();
</script>
</html>

推荐文章:php安装swoole扩展的方法    使用swoole扩展php websocket示例

以上代码给大家分享了PHP+swoole实现简单多人在线聊天群发的相关代码,希望本文所述对大家有所帮助。

您可能感兴趣的文章:
  • PHP框架实现WebSocket在线聊天通讯系统
  • ThinkPHP5.0框架结合Swoole开发实现WebSocket在线聊天案例详解
  • Ajax PHP JavaScript MySQL实现简易无刷新在线聊天室
  • 基于javascript、ajax、memcache和PHP实现的简易在线聊天室
  • PHP聊天室简单实现方法详解
  • 基于Swoole实现PHP与websocket聊天室
  • 值得分享的php+ajax实时聊天室
  • 简单的php+mysql聊天室实现方法(附源码)
  • php实现简易聊天室应用代码
  • php+html5基于websocket实现聊天室的方法
  • 基于PHP实现一个简单的在线聊天功能

java实现多人在线聊天室

java实现多人在线聊天室

首先,我们要明确几件事。

聊天室需要具有什么功能?

1、存在n个未与Server建立连接的Client。当第一个Client与Server建立连接,紧接着第二个Client与Server建立连接后,Server会在控制台上

打印“xxx已上线”。当n个Client与Server建立连接之后,第n+1个Client建立连接后,Server会通知其他Client:“xxx已上线”。        ------聊天室的广播机制

2、建立IO流,Client之间互为输出流,Server作为消息转发的载体,需要同步。                     ------聊天室的消息回调机制

 

当连接一旦建立好,相应的处理器是HandlerAdded(ChannelHandlerContext ctx),所以要先获取channel对象。但要想广播出去,Server需要保存好所有建立连

接的channel对象。如何保存?用netty提供的channelGroup,定义这个实例,用DefaultChannelGroup对象实现。生成channelGroup对象后那channel对象add到

channelGroup中。在add之前,遍历channelGroup的每个对象,就实现了广播机制。

在使用channel.remoteAddress()方法拿到连接后,重写SimpChannelHandler的子类方法channelRead0()即可。在channelRead0中,用forEach()遍历channelGroup。

如果是别的Client通过readLine()发送的消息,则打印channel.remoteAddress()和msg,如果是自己发送的消息就只打印msg,这就实现了消息回调机制。

 

Server \

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * @description:    【聊天---服务器处理】
* @author: KlayHu
 * @create: 2019/10/8 17:23
 **/
public class MyChatServerHandler extends SimpleChannelInboundHandler<String>{


    //定义保存建立连接的Channel对象的实例
private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);


@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg) throws Exception {
        Channel channel = ctx.channel();

channelGroup.forEach(ch->{
            if(channel!=ch){
                ch.writeAndFlush("【" + channel.remoteAddress() +"】" + "发送的消息:" + msg + "\n");
}else{
                ch.writeAndFlush("【我:】" + msg + "\n");
}
        });


}


    @Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();

channelGroup.writeAndFlush("【服务器:】-" + channel.remoteAddress() + "=======已加入!=======\n");     //遍历每一个channel对象,新连接的channel的远程地址告诉别的client它加入了。
channelGroup.add(channel);
}

    @Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();        //获取channel对象
channelGroup.writeAndFlush("【服务器:】-" + channel.remoteAddress() + "=======已离开!=======\n");

System.out.println(channelGroup.size());    //当有客户端断开连接的时候,没有必要调用Remove,验证一下。
//channelGroup.remove(channel);     netty会自动调用
}


    @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
System.out.println("【" + channel.remoteAddress() + "】" + "====上线了====");
}


    @Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
System.out.println("【" + channel.remoteAddress() + "】" + "====下线了====");
}

    @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {

    }
}

 Client \

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * @description:    【聊天---客户端】
 * @author: KlayHu
 * @create: 2019/10/8 18:40
 **/
public class MyChatClient {
    public static void main(String[] args) throws Exception{
        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();
        try{
            Bootstrap bootstrap = new Bootstrap();

            bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class).handler(new MyChatClientInitializer());

            Channel channel = bootstrap.connect("localhost",8888).sync().channel();
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            for(;;){
                channel.writeAndFlush(br.readLine() + "\r\n");
            }

        }finally {
            eventLoopGroup.shutdownGracefully();
        }
    }
}

 

关于Server和Client的事件循环组和启动配置类的建立在上一篇中与本篇写法大致相同。netty的独特性,就在于自定义的Handler。

【服务器】

 

 

 【客户端1】

  

 

【客户端2】

 

 

 【客户端3】

 

 

 

 

 

 

 

 

 

 

Java通过Socket实现简单多人聊天室

Java通过Socket实现简单多人聊天室

这篇文章主要为大家详细介绍了Java通过Socket实现简单多人聊天室,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Java通过Socket实现多人聊天室的具体代码,供大家参考,具体内容如下

Socket可以实现网络上两个程序通过双向通道进行数据的交换,此外它是Java中网络TCP/IP协议的封装,例如可以进行网络通信等等,下面我们就来简单写一下多人聊天室。

首先来分析一下要实现的流程

首先建立一个服务器端,构建ServerSocket并绑定端口

创建socket客户端,连接到指定ip以及其端口

然后使用accept阻塞接收socket发出的连接请求

获取连接后的socket客户端的输入流和输出流

根据输入流和输出流进行两者数据的通信

值得一提是:该Socket是同步阻塞的,因此在socket客户端需要进行创建一个线程,来分别进行向服务器输出,和接收服务器传输的数据。要解决同步阻塞这个问题可以去了解JAVA NIO。

Socket客户端代码如下:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.socket; public class Client{ public static void main(String[] args) throws IOException { //创建连接指定Ip和端口的socket Socket socket = new Socket("127.0.0.1",5200); //获取系统标准输入流 BufferedReader reader = new BufferedReader(new InputStreamReader(system.in)); PrintWriter out = new PrintWriter(socket.getoutputStream()); BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //创建一个线程用于读取服务器的信息 new Thread(new Runnable() { @Override public void run() { try { while (true){ System.out.println(in.readLine()); } } catch (IOException e) { e.printstacktrace(); } } }).start(); //写信息给客户端 String line = reader.readLine(); while (!"end".equalsIgnoreCase(line)){ //将从键盘获取的信息给到服务器 out.println(line); out.flush(); //显示输入的信息 line = reader.readLine(); } out.close(); in.close(); socket.close(); } }

由于要接收多个客户端的请求,因此服务端需要多个线程进行分别来接收客户端的请求。

Socket服务端代码如下:

import java.io.IOException; import java.net.ServerSocket; import java.net.socket; import java.util.List; import java.util.Vector; public class Servers { //将接收到的socket变成一个集合 protected static List sockets = new Vector(); public static void main(String[] args) throws IOException { //创建服务端 ServerSocket server = new ServerSocket(5200); boolean flag = true; //接受客户端请求 while (flag){ try { //阻塞等待客户端的连接 Socket accept = server.accept(); synchronized (sockets){ sockets.add(accept); } //多个服务器线程进行对客户端的响应 Thread thread = new Thread(new ServerThead(accept)); thread.start(); //捕获异常。 }catch (Exception e){ flag = false; e.printstacktrace(); } } //关闭服务器 server.close(); } }

Server线程代码如下:

import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.socket; /** * 服务器线程,主要来处理多个客户端的请求 */ public class ServerThead extends Servers implements Runnable{ Socket socket; String socketName; public ServerThead(Socket socket){ this.socket = socket; } @Override public void run() { try { BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); //设置该客户端的端点地址 socketName = socket.getRemoteSocketAddress().toString(); System.out.println("Client@"+socketName+"已加入聊天"); print("Client@"+socketName+"已加入聊天"); boolean flag = true; while (flag) { //阻塞,等待该客户端的输出流 String line = reader.readLine(); //若客户端退出,则退出连接。 if (line == null){ flag = false; continue; } String msg = "Client@"+socketName+":"+line; System.out.println(msg); //向在线客户端输出信息 print(msg); } closeConnect(); } catch (IOException e) { try { closeConnect(); } catch (IOException e1) { e1.printstacktrace(); } } } /** * 向所有在线客户端socket转发消息 * @param msg * @throws IOException */ private void print(String msg) throws IOException { PrintWriter out = null; synchronized (sockets){ for (Socket sc : sockets){ out = new PrintWriter(sc.getoutputStream()); out.println(msg); out.flush(); } } } /** * 关闭该socket的连接 * @throws IOException */ public void closeConnect() throws IOException { System.out.println("Client@"+socketName+"已退出聊天"); print("Client@"+socketName+"已退出聊天"); //移除没连接上的客户端 synchronized (sockets){ sockets.remove(socket); } socket.close(); } }

由于要接收多个客户端的信息,并转发到每一个已经连接上的客户端,因此创建了一个Vector集合来保存每一个客户端Socket,由于是多个线程同时对这个Vector集合进行操作,因此加上synchronized关键字保证同步安全。

先运行服务器端,然后在运行多个客户端就可以进行多人聊天了。

下面是运行的结果。

 

客户端2

 

客户端1

 

客户端3

服务端

PHP + Swoole 简单聊天室

PHP + Swoole 简单聊天室

Chatroom

PHP + Swoole 开发的简单聊天室demo, 主要是 websockt 的应用 。

环境要求

  • PHP >= 7.0
  • Swoole
  • composer

项目地址

https://github.com/kesixin/Ch...

安装

git clone https://github.com/kesixin/Chatroom
composer install

启动 websockt

cd ./webim
php webim_server.php

启动 PHP 内置服务器

cd ./public
php -S localhost:8000

浏览器访问 localhost:8000 即可进入聊天

截图

效果图

项目测试地址

http://test.kesixin.xin/ ,由于没开启端口,可能无法运行,需要请联系!

php swoole实现简单redis连接池

php swoole实现简单redis连接池

<?php declare(strict_types=1);

Co\run(function(){
    go(function(){
        redisPool::i();
        for ($c=1000;$c--;){
            $pool = RedisPool::i();
            $redis = $pool->get();
            defer(function() use($pool,$redis){
                $pool->put($redis);
            });
            $value = $redis->get(''foo'');
            if($value === false){
                throw new RuntimeException(''get undefined'');
            }

            assert($value,''bar'');
        }
    });
});



class RedisPool
{
    protected $channel;
    protected static $instance;

    public static function i() : self
    {
        return !empty(static::$instance) ? static::$instance : (static::$instance = new static());
    }

    public function __construct(int $size=100)
    {
        $this->channel = new Swoole\Coroutine\Channel($size);
        while ($size --)
        {
            $redis = new Swoole\Coroutine\Redis();
            $res = $redis->connect(''127.0.0.1'',6379);
            if($res === true){
                $this->put($redis);
            }else{
                throw new RuntimeException(''cannot connect redis'');
            }
        }
    }

    public function put(Swoole\Coroutine\Redis $redis) : void
    {
        $this->channel->push($redis);
    }

    public function get(float $timeout = -1) : ?Swoole\Coroutine\Redis
    {
        return $this->channel->pop($timeout) ? : null;
    }

    public function close()
    {
        return $this->channel->close();
    }
}

注意点:

/etc/php.ini  配置 swoole.use_shortname = On  开启swoole go 函数的短函数的使用

我们今天的关于PHP+swoole实现简单多人在线聊天群发php即时多人聊天的分享已经告一段落,感谢您的关注,如果您想了解更多关于java实现多人在线聊天室、Java通过Socket实现简单多人聊天室、PHP + Swoole 简单聊天室、php swoole实现简单redis连接池的相关信息,请在本站查询。

本文标签: