对于PHP+swoole实现简单多人在线聊天群发感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解php即时多人聊天,并且为您提供关于java实现多人在线聊天室、Java通过Socket实现简
对于PHP+swoole实现简单多人在线聊天群发感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解php即时多人聊天,并且为您提供关于java实现多人在线聊天室、Java通过Socket实现简单多人聊天室、PHP + Swoole 简单聊天室、php swoole实现简单redis连接池的宝贵知识。
本文目录一览:- PHP+swoole实现简单多人在线聊天群发(php即时多人聊天)
- java实现多人在线聊天室
- Java通过Socket实现简单多人聊天室
- PHP + Swoole 简单聊天室
- php swoole实现简单redis连接池
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实现多人在线聊天室
首先,我们要明确几件事。
聊天室需要具有什么功能?
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实现多人聊天室的具体代码,供大家参考,具体内容如下
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 简单聊天室
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 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连接池的相关信息,请在本站查询。
本文标签: