websocke和基于swoole的异步通信

一、概述

  WebSocket 协议是HTML5开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。

  在WebSocket API中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。浏览器通过 JavaScript 向服务器发出建立 WebSocket 连接的请求,连接建立以后,客户端和服务器端就可以通过 TCP 连接直接交换数据。当你获取 Web Socket 连接后,你可以通过 send() 方法来向服务器发送数据,并通过 onmessage 事件来接收服务器返回的数据。

  WebSocket API最伟大之处在于服务器和客户端可以在给定的时间范围内的任意时刻,相互推送信息。WebSocket并不限于以Ajax(或XHR)方式通信,因为Ajax技术需要客户端发起请求,而WebSocket服务器和客户端可以彼此相互推送信息;XHR受到域的限制,而WebSocket允许跨域通信。

二、HTML5+NodeJs实现WebSocket即时通讯

参考:http://www.cnblogs.com/axes/p/3586132.html

准备知识:

  1. 服务器端语言:nodeJs(类似PHP)

  2. nodeJs 管理包工具 npm(类似composer)

    步骤1:安装nodejs
    步骤2:安装npm(淘宝镜像http://npm.taobao.org并定制命令cnpm)
    步骤3:在cmd运行初始化命令: npm init
    步骤4:安装nodeJs的模块nodejs-websocke,运行命令:cnpm install nodejs-websocket
    安装成功

    步骤5:将websocket包的监听js代码放到test.js,包网站:https://www.npmjs.com/package/nodejs-websocket

    步骤6:运行node test.js

    步骤7:打开game1、game2

game1.html

game2.html

这里写图片描述

三、基于Swoole的websocket
web聊天UI
<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <title>聊天会话</title>

    <style>
        #content .left{
            text-align: left;
        }
        #content .right{
            text-align: right;
        }
    </style>
</head>

<body>
<div id="cc" style="width:700px;">
    发送用户id:<input type="text" name="user" >
    接收用户id:<input type="text" name="to_user" >
    <button class="login">登录</button>
    <div id="content" style=" height:400px; overflow:auto; width:100%; border:1px solid #ccc;"></div>
    <form id="form">
        <textarea id="texts" style="width:100%; height:200px;"></textarea>
        <input type="button" onclick="ab();" value="发送">
    </form>
</div>
<script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
<script>

    var uid,toUid;

    $('.login').on('click' , function(){
        uid = $('[name=user]').val().trim();
        toUid = $('[name=to_user]').val().trim();
        if(uid == '' || toUid == ''){
            alert('请先登录');
        }else{
            aa(uid ,toUid );
        }
    })


    var socket;

    function aa(uid , toUid )
    {

        socket=new WebSocket('ws://192.168.82.31:9502?uid=' + uid );

        socket.onopen=function()
        {
            console.log('用户id:' , uid);
            var msg = setMsg(1 , '链接成功' , uid  , toUid ) ;
            console.log(msg);
            socket.send( msg );
        }

        socket.onmessage=function(msg)
        {
            $('#content').append('<p class="b left"> '+msg.data+'</p>');
        }

        socket.onclose= function()
        {
            $('#content').append('<p class="c">退出聊天室</p>');
        }
    }

    function ab()
    {
        var msg = $('#texts').val();
        var sendmsg = setMsg( 2 , msg , uid , toUid );
        socket.send( sendmsg );
        $('#content').append('<p class="b right">'+msg+': 我(uid:'+uid+')</p>');
        $('#texts').val('');
    }

    function az()
    {
        socket.close();
        socket=null;
    }


    function setMsg( type , msg , uid ,toUid ){
        var msgObject = {
            type : type ,
            msg: msg ,
            uid: uid ,
            to_uid: toUid
        }
        return JSON.stringify(msgObject);
    }
</script>
</body>
</html>
服务端开启监听websocket事件
<?php
// server.php 
// 所有登录用户的fd
$userFdList = [];
//创建websocket服务器对象,监听0.0.0.0:9502端口
$ws = new swoole_websocket_server("0.0.0.0", 9502);
//监听WebSocket连接打开事件
$ws->on('open', function ($ws, $request) use (&$userFdList) {

	$userFdList[$request->get['uid']] = $request->fd ;
	//var_dump($request);
    //var_dump($request->fd, $request->get, $request->server);
    $ws->push($request->fd, "系统:hello, welcome\n");
    // echo '所有正在连接的用户:';
    // print_r($userFdList);
});

//监听WebSocket消息事件
$ws->on('message', function ($ws, $frame) use (&$userFdList) {
	echo '所有正在连接的用户:';
    print_r($userFdList);
	echo 'Message:<pre>';
	$data = json_decode($frame->data , true);
    print_r($data);

    if($data['type'] == 1){
    	$ws->push($userFdList[$data['uid']], "系统:{$data['msg']}");
    } else if( !isset($userFdList[$data['to_uid']])) {
    	$ws->push($userFdList[$data['uid']], "系统:用户没上线");
    } else {
    	$ws->push($userFdList[$data['to_uid']], "别人(uid:{$data['uid']}):{$data['msg']}");
    }
    
});

//监听WebSocket连接关闭事件
$ws->on('close', function ($ws, $fd) use (&$userFdList) {

	foreach ($userFdList as $key => $value) {
		if( $value == $fd ) unset($userFdList[$key]);
	}
    echo "client-{$fd} is closed\n";
});

$ws->start();

  1. 在服务端开启监听:php server.php ;( php必须支持swoole )
  2. 在浏览器登录账号:
    在这里插入图片描述
在服务端监听成功:

在这里插入图片描述

在另一浏览器窗口登录另一个账号:

在这里插入图片描述

以上步骤就实现简单的web聊天功能,两个浏览器之间可以互发消息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值