• 代码千万行,注释第一行。命名不规范,同事泪千行。

[即时通讯]使用php写服务端,html和c#winfrom写客户端[弃坑中]

ASP.NET Secondar 9个月前 (02-11) 337次浏览 已收录 0个评论

下载地址:https://github.com/secondar/phpsocker

php部分

<?php
error_reporting(E_ALL);
set_time_limit(0);// 设置超时时间为无限,防止超时
date_default_timezone_set('Asia/shanghai');
$sk=new ws('192.168.1.85','8080');
/**
 *
 */
class ws{
    private $objMaster;
    private $arrSockets;
    private $arrUsers;
    function __construct($host,$port,$linux=false){
        try {
            //创建服务端的socket套接流,net协议为IPv4,protocol协议为TCP
            $this->objMaster = socket_create(AF_INET,SOCK_STREAM,SOL_TCP) or die("err => socket_create\n");
            $strSeverName = '';
            if($linux){
                $strSeverName = posix_getpid();
            }else{
                $strSeverName = get_current_user();
            }
            $this->debug('info : '.date('Y-m-d H:i:s').' | '.$strSeverName.' -> socket_create');
            //设置IP和端口重用,在重启服务器后能重新使用此端口;
            socket_set_option($this->objMaster, SOL_SOCKET, SO_REUSEADDR, 1) or die("err => socket_set_option");
            $this->debug('info : '.date('Y-m-d H:i:s').' | '.$strSeverName.' -> socket_set_option');
            //绑定接收的套接流主机和端口,与客户端相对应
            socket_bind($this->objMaster,$host,$port) or die("err => socket_bind");
            $this->debug('info : '.date('Y-m-d H:i:s').' | '.$strSeverName.' -> socket_bind');
            //监听套接流
            socket_listen($this->objMaster) or die("err => socket_listen");
            $this->debug('info : '.date('Y-m-d H:i:s').' | '.$strSeverName.' -> socket_listen');
        }catch(\Exception $e){
            $this->debug( 'info : '.date('Y-m-d H:i:s').' | '.$strSeverName.' | server listen fail -> '.socket_strerror(socket_last_error()));
        }
        $this->arrSockets[0] = $this->objMaster;
        $this->arrUsers['server']=array('resource'=>$this->objMaster,'name'=>'sever','handshake'=>true);
        $this->run();
        $this->debug('info : '.date('Y-m-d H:i:s').' | '.$strSeverName.' -> run');
    }
    private function run(){
        while (true) {
            $arrChanges=$this->arrSockets;
            $write=NULL;
            $except=NULL;
            /*
            这个函数是同时接受多个连接的关键,我的理解它是为了阻塞程序继续往下执行。
            socket_select ($arrSockets, $write = NULL, $except = NULL, NULL);
            $arrSockets可以理解为一个数组,这个数组中存放的是文件描述符。当它有变化(就是有新消息到或者有客户端连接/断开)时,socket_select函数才会返回,继续往下执行。
            $write是监听是否有客户端写数据,传入NULL是不关心是否有写变化。
            $except是$arrSockets里面要被排除的元素,传入NULL是”监听”全部。
            最后一个参数是超时时间
            如果为0:则立即结束
            如果为n>1: 则最多在n秒后结束,如遇某一个连接有新动态,则提前返回
            如果为null:如遇某一个连接有新动态,则返回
            */
            socket_select($arrChanges,$write,$except,NULL) or die("err => socket_select ,".socket_last_error().
                socket_strerror(socket_last_error())."\n");
            foreach($arrChanges as $Socket){
                /*新连接到来时,被监听的端口是活跃的,如果是新数据到来或者客户端关闭链接时,活跃的是对应的客户端socket而不是服务器上被监听的端口
                如果客户端发来数据没有被读走,则socket_select将会始终显示客户端是活跃状态并将其保存在readfds数组中
                如果客户端先关闭了,则必须手动关闭服务器上相对应的客户端socket,否则socket_select也始终显示该客户端活跃(这个道理跟"有新连接到来然后没有用socket_access把它读出来,导致监听的端口一直活跃"是一样的)*/

                //如果有新的client连接进来
                if($Socket==$this->objMaster){
                    //接受一个socket连接
                    $objClient=socket_accept($this->objMaster);
                    //给新连接进来的socket一个唯一的ID
                    $key=uniqid();
                    $this->arrSockets[]=$objClient;     //将新连接进来的socket存进连接池
                    $this->arrUsers[$key]=array(
                        'resource'=>$objClient,        //记录新连接进来client的socket信息
                        'handshake'=>false             //标志该socket资源没有完成握手
                    );
                    $this->debug('info : '.date('Y-m-d H:i:s').' | key:'.$key.' | resource:'.$objClient.' -> Connect');
                }else{//否则1.为client断开socket连接,2.client发送信息
                    @$intLen = socket_recv($Socket, $objBuffer, 8192, 0);
                    $strUsers_Key=$this->search_key($Socket);
                    //如果接收的信息长度小于9,则该client的socket为断开连接
                    if($intLen<9){
                        //给该client的socket进行断开操作,并在$this->sockets和$this->users里面进行删除
                        $this->close($strUsers_Key);
                        continue;
                    }
                    //判断该socket是否已经握手
                    if(!$this->arrUsers[$strUsers_Key]['handshake']){
                        $this->connect($strUsers_Key,$objBuffer);
                    }else{
                        $arrMsg=$this->parse($objBuffer);
                        print_r(array($objBuffer));//exit();
                        if($arrMsg==false){
                            $arrMsg=json_decode($objBuffer,true);//给C#客户端用
                            print_r(array($arrMsg));
                            if($arrMsg==false){
                                continue;
                            }
                        }
                        switch ($arrMsg['type']) {
                            case 'login':
                                $arrMsg['uid']=rand(intval(time()/2),time());
                                $this->response_login($arrMsg,$strUsers_Key);
                                break;
                            case 'user_msg':
                                $arrMsg['from']=$this->arrUsers[$strUsers_Key]['name'];
                                $this-> broadcast($arrMsg,$arrMsg['uid'],$strUsers_Key);
                                break;
                        }
                        //如果不为空,则进行消息推送操作
                    }
                }
            }
        }
    }
    /**
     * [search_key 根据Socket在arrUsers里面查找相应的key]
     * @param  [type] $Socket [Socket]
     * @return [string]         [查询到的key]
     */
    private function search_key($Socket){
        foreach ($this->arrUsers as $k=>$v){
            if($Socket==$v['resource'])
            return $k;
        }
        return false;
    }
    /**
     * [close 指定关闭$k对应的socket]
     * @param  [string] $key [socket对应的$k]
     * @return [void]
     */
    private function close($key){
        $log='info : '.date('Y-m-d H:i:s').' | key : '.$key.' | resource : '.$this->arrUsers[$key]['resource'].' -> close';
        //断开相应socket
        socket_close($this->arrUsers[$key]['resource']);
        //删除相应的user信息
        unset($this->arrUsers[$key]);
        //重新定义sockets连接池
        $this->arrSockets = array();
        foreach($this->arrUsers as $v){
            $this->arrSockets[]=$v['resource'];
        }
        $this->debug($log);
    }
    /**
     * [debug 输出日志信息]
     * @param  [string] $str [需要输出的文本信息]
     * @return [void]
     */
    private function debug($str){
        $str=$str."\n";
        echo iconv('utf-8','gbk//IGNORE',$str);
    }
    /**
     * [connect 对client的请求进行回应,即握手操作]
     * @param  [string] $key    [clien的socket对应的健,即每个用户有唯一$k并对应socket]
     * @param  [type] $buffer [接收client请求的所有信息]
     * @return [bool]
     */
    private function connect($key,$buffer){
        //截取Sec-WebSocket-Key的值并加密,其中$key后面的一部分258EAFA5-E914-47DA-95CA-C5AB0DC85B11字符串应该是固定的
        $buf  = substr($buffer,strpos($buffer,'Sec-WebSocket-Key:')+18);
        $key_encrypt  = trim(substr($buf,0,strpos($buf,"\r\n")));
        $new_key = base64_encode(sha1($key_encrypt."258EAFA5-E914-47DA-95CA-C5AB0DC85B11",true));
        //按照协议组合信息进行返回
        $new_message = "HTTP/1.1 101 Switching Protocols\r\n";
        $new_message .= "Upgrade: websocket\r\n";
        $new_message .= "Sec-WebSocket-Version: 13\r\n";
        $new_message .= "Connection: Upgrade\r\n";
        $new_message .= "Sec-WebSocket-Accept: " . $new_key . "\r\n\r\n";
        socket_write($this->arrUsers[$key]['resource'],$new_message,strlen($new_message));
        //对已经握手的client做标志
        $this->arrUsers[$key]['handshake']=true;
        return true;
    }
    /**
     * [parse 解析数据]
     * @param  [type] $buffer  [接收client请求的所有信息]
     * @return [array]         [处理好的信息]
     */
    private function parse($buffer) {
        $decoded = '';
        $len = ord($buffer[1]) & 127;
        if ($len === 126) {
            $masks = substr($buffer, 4, 4);
            $data = substr($buffer, 8);
        } else if ($len === 127) {
            $masks = substr($buffer, 10, 4);
            $data = substr($buffer, 14);
        } else {
            $masks = substr($buffer, 2, 4);
            $data = substr($buffer, 6);
        }
        for ($index = 0; $index < strlen($data); $index++) {
            $decoded .= $data[$index] ^ $masks[$index % 4];
        }

        return json_decode($decoded, true);
    }
    /**
     * [build 将普通信息组装成websocket数据帧]
     * @param  [type] $msg         [对编码后的json]
     * @return [bool|string]      [description]
     */
    private function build($arrmsg) {
        $frame = [];
        $frame[0] = '81';
        $len = strlen($arrmsg);
        if ($len < 126) {
            $frame[1] = $len < 16 ? '0' . dechex($len) : dechex($len);
        } else if ($len < 65025) {
            $s = dechex($len);
            $frame[1] = '7e' . str_repeat('0', 4 - strlen($s)) . $s;
        } else {
            $s = dechex($len);
            $frame[1] = '7f' . str_repeat('0', 16 - strlen($s)) . $s;
        }
        $data = '';
        $l = strlen($arrmsg);
        for ($i = 0; $i < $l; $i++) {
            $data .= dechex(ord($arrmsg{$i}));
        }
        $frame[2] = $data;
        $data = implode('', $frame);
        return pack("H*", $data);
    }
    /**
     * [broadcast 发送消息]
     * @param  [array] $data [build处理好的数据]
     * @return [type]       [description]
     */
    private function broadcast($msg_content,$uid='all',$mykey) {
        if(empty($msg_content['content'])&&$msg_content['content']!=0){
            $this->debug('info : '.date('Y-m-d H:i:s').' | function:broadcast'.' | content is null -> err');
        }
        if(empty($msg_content['type'])){
            $this->debug('info : '.date('Y-m-d H:i:s').' | function:broadcast'.' | type is null -> err');
        }
        if(empty($msg_content['from'])){
            $this->debug('info : '.date('Y-m-d H:i:s').' | function:broadcast'.' | from is null -> err');
        }
        if($mykey){
            $this->debug('info : '.date('Y-m-d H:i:s').' | function:broadcast'.' | mykey is null -> err');
        }
        $data=$this->build(json_encode($msg_content));
        if($uid=='all'){
            foreach ($this->arrSockets as $Socket) {
                if ($Socket == $this->objMaster) {
                    continue;
                }
                socket_write($Socket, $data, strlen($data));
            }
        }else{
            $key=$this->search_uid($uid);
            socket_write($this->arrUsers[$key]['resource'], $data, strlen($data));
            socket_write($this->arrUsers[$mykey]['resource'], $data, strlen($data));
        }
    }
    /**
     * [response_login 登录信息]
     * @param  [array]  $arrmsg [信息数组]
     * @param  [string] $key    [description]
     * @return [void]
     */
    private function response_login($arrmsg,$key) {
        $this->arrUsers[$key]['name']=$arrmsg['name'];
        $this->arrUsers[$key]['uid']=$arrmsg['uid'];
        $response['type'] = 'system';
        $response['from'] = 'login';
        $response['name'] = $arrmsg['name'];
        $response['content'] = 'ok';
        $response['user_list_count'] = count($this->arrUsers)-1;
        $response['user_list'] = $this->get_userlist();
        $data=$this->build(json_encode($response));
        socket_write($this->arrUsers[$key]['resource'], $data, strlen($data));
        $this->update_list($arrmsg['name'],$key);
    }
    private function update_list($name,$key) {
        $response['name'] = $name;
        $response['type'] = 'system';
        $response['from'] = 'list';
        $response['content'] = 'ok';
        $response['user_list_count'] = count($this->arrUsers)-1;
        $response['user_list'] = $this->get_userlist();
        $data=$this->build(json_encode($response));
        // socket_write($this->arrUsers[$key]['resource'], $data, strlen($data));
        foreach ($this->arrSockets as $Socket) {
            if ($Socket == $this->objMaster) {
                continue;
            }
            socket_write($Socket, $data, strlen($data));
        }
    }
    private function get_userlist(){
        $arrUserlist=array();
        foreach ($this->arrUsers as $k => $v) {
            if($k != 'server'){
                $arrUserlist[]=array('uid'=>$v['uid'],'name'=>$v['name']);
            }
        }
        return $arrUserlist;
    }
    /**
     * [search_uid 根据UID查找KEY]
     * @param  [type] $uid [客户端UID]
     * @return [string]    [对应的KEY]
     */
    private function search_uid($uid){
        if(!empty($uid)){
            foreach ($this->arrUsers as $k => $v){
                if($k != 'server'){
                    if($v['uid']==$uid){
                        return $k;
                    }
                }
            }
        }
    }
}
?>

html部分

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8">
    <style>
        p {
            text-align: left;
            padding-left: 20px;
        }
        a:link { text-decoration: none;color: black}
        a:active { text-decoration:blink}
        a:hover { text-decoration:underline;color: red} 
        a:visited { text-decoration: none;color: green}
    </style>
</head>
<body>
<div style="width: 800px;height: 600px;margin: 30px auto;text-align: center">
    <div style="width: 800px;border: 1px solid gray;height: 100%;">
        <div style="width: 130px;height: 300px;float: left;text-align: left;">
            <div id="user_list" style="overflow: auto;">
            </div>
             <p><span>当前在线:</span><span id="user_num">0</span></p>
        </div>
        <div id="msg_list" style="width: 83.5%;border:  1px solid gray; height: 99.9%;;overflow: scroll;float: left;">
        </div>
    <br>
    <textarea id="msg_box" rows="6" cols="50" onkeydown="confirm(event)" style="width: 800px; height: 50px"></textarea><br>
    <input type="file" id="img_upload" style="display:none;" value="图片" />
    <input type="button" id="img_button" value="图片" onclick="img_upload.click()" style="width: 200px; height: 50px;float: left;">
    <input type="button" id='send_button' value="发送" onclick="send()" style="width: 600px; height: 50px">
</div>
</body>
</html>

<script type="text/javascript">
    // 存储用户名到全局变量,握手成功后发送给服务器
    var img=Array();
    var img_upload=document.getElementById("img_upload");
    img_upload.addEventListener('change',readFile,false);
    var send_button=document.getElementById("send_button");
    var user_id='all';
    var u_name = '';
    var uname = prompt('请输入用户名',);
    var uid = '';

    var ws = new WebSocket("ws://192.168.1.85:8080");
    ws.onopen = function () {
        var user_info = {'type': 'login', 'name': uname,'uid':uid};
        sendMsg(user_info);
    };
    /**
     * 分析服务器返回信息
     *
     * msg.type : user 普通信息;system 系统信息;handshake 握手信息;login 登陆信息; logout 退出信息;
     * msg.from : 消息来源
     * msg.content: 消息内容
     */
    ws.onmessage = function (e) {
        var bool =false;
        var msg = JSON.parse(e.data);
        var sender, user_name, user_list_count, change_type;
        console.log(msg);/////////////////////////////
        switch (msg.type) {
            case 'system':
                switch(msg.from){
                    case 'system':
                        sender = '系统消息 : ';
                        bool=true;
                    break;
                    case 'login':
                        sender = '系统消息 -> 登录状态 -> ';
                        user_name = msg.name;
                        change_type = msg.from;
                        uid = msg.uid;
                        bool=true;
                    break;
                    case 'list':
                        user_name = msg.name;
                        user_list_count = msg.user_list_count;
                        user_list = msg.user_list;
                        change_type = msg.from;
                        dealUser(user_name, change_type, user_list_count,user_list);
                        bool=false;
                    break;
                }
                break;
            case 'user_msg':
                switch(msg.msg_type){
                    case 'img':
                        switch(msg.img_state){
                            case 'end':
                                img[msg.from]+=msg.content;
                                sender = msg.from + ':';
                                msg.content='<img src="'+img[msg.from]+'" alt="" style="width: 100%;height: 100%" />';
                                bool=true;
                            break;
                            case 'start':
                                img[msg.from]='';
                                img[msg.from]+=msg.content;
                            break;
                            default:
                                img[msg.from]+=msg.content;
                            break;
                        }
                    break;
                    case 'txt':
                        if(msg.uid=='all'){
                            sender = msg.from + ': ';
                        }else{
                            if(msg.uid==uid){
                                sender = msg.from + ' 对你说: ';
                            }else{
                                sender =  '你对'+u_name+ '说: ';
                            }
                        }
                        msg.content=msg.content.replace(/</g, "<").replace(/>/g, ">");
                        bool=true;
                    break;
                }
                break;
        }
        if(bool){
            var data = sender + msg.content;
            listMsg(data);
        }
    };
    ws.onerror = function () {
        var data = "系统消息 : 连接退出.";
        listMsg(data);
    };
    ws.onclose=function(){
        var data = "系统消息 : 服务端关闭.";
        listMsg(data);
    }
    /**
     * 在输入框内按下回车键时发送消息
     *
     * @param event
     *
     * @returns {boolean}
     */
    function confirm(event) {
        var key_num = event.keyCode;
        if (13 == key_num) {
            send();
        } else {
            return false;
        }
    }
    /**
     * 发送并清空消息输入框内的消息
     */
    function send() {
        var msg_box = document.getElementById("msg_box");
        var content = msg_box.value;
        var reg = new RegExp("\r\n", "g");
        content = content.replace(reg, "");
        var msg = {'content': content.trim(), 'type': 'user_msg','msg_type': 'txt','uid':user_id};
        if(user_id==uid){
            alert('不能与自己对话!');
        }else{
            sendMsg(msg);
        }
        msg_box.value = '';
        // todo 清除换行符
    }
    /**
     * 将消息内容添加到输出框中,并将滚动条滚动到最下方
     */
    function listMsg(data) {
        var msg_list = document.getElementById("msg_list");
        var msg = document.createElement("p");
        msg.innerHTML = data;
        msg_list.appendChild(msg);
        msg_list.scrollTop = msg_list.scrollHeight;
    }
    /**
     * 处理用户登陆消息
     *
     * @param user_name 用户名
     * @param type  login/logout
     * @param name_list 用户列表
     */
    function dealUser(user_name, type, name_list_count,user_list) {
        var user_list_dom = document.getElementById("user_list");
        var user_num = document.getElementById("user_num");
        user_list_dom.innerHTML='';
        var lis = document.createElement("p");
        lis.innerHTML = "<a id='a_all' href=\"javascript:void(0);\" onclick=\"checkedid('all','所有人')\">所有人</a>";
        user_list_dom.appendChild(lis);
        for (var i = 0; i < user_list.length; i++) {
            lis = document.createElement("p");
            lis.innerHTML = "<a id='a_"+user_list[i].uid+"' href=\"javascript:void(0);\" onclick=\"checkedid('"+user_list[i].uid+"','"+user_list[i].name+"')\">"+user_list[i].name+"</a>";
            user_list_dom.appendChild(lis);
        }
        user_num.innerHTML = name_list_count;
        user_list_dom.scrollTop = user_list_dom.scrollHeight;
        var change = type == 'list' ? '上线' : '下线';
        var data = '系统消息: ' + user_name + ' 已' + change;
        listMsg(data);
    }
    /**
     * 将数据转为json并发送
     * @param msg
     */
    function sendMsg(msg) {
        var data = JSON.stringify(msg);
        // console.log(data);
        ws.send(data);
    }
    function readFile(){
            var file=this.files[0];
            if(!/image\/\w+/.test(file.type)){ 
                alert("请确保文件为图像类型"); 
                return false; 
            }
            var reader=new FileReader();
            reader.readAsDataURL(file);
            reader.onload=function(){
                if(this.result.length>1399895){
                    alert('图片不能大于1MB否则不保证质量');
                    return;
                }
                var while_i=0;
                var len=1024;
                var img_i=0;
                var img=Array();
                while(true){
                    content=this.result.substr(while_i,len);
                    if(this.result.length<=while_i){
                        break;
                    }
                    var leni=while_i;
                    while_i+=len;
                    if(while_i>=this.result.length){
                        len=this.result.length;
                    }
                    img[img_i]=content;
                    img_i++;
                }
                var time=50;
                var senlen=0;
                var reslen=this.result.length;
                for(var i=0;i<img.length;i++){
                    (function(i){
                        setTimeout(function(){
                            senlen+=img[i].length;
                            img_button.value='发送中:'+senlen+'/'+reslen;
                            if(i==0){
                                msg = {'img_state': 'start', 'type': 'user_msg','msg_type': 'img','content': img[i],'uid':user_id};
                                sendMsg(msg);
                            }else if((i+1)==img.length){
                                msg = {'img_state': 'end', 'type': 'user_msg','msg_type': 'img','content': img[i],'uid':user_id};
                                sendMsg(msg);
                                img_button.value='图片';
                            }else{
                                msg = {'img_state': 'body','content': img[i], 'type': 'user_msg','msg_type': 'img','uid':user_id};
                                sendMsg(msg);
                            }
                        }, time);
                    })(i)
                    time+=10;
                }
            }
    }
    function checkedid(id,name){
        console.log(user_id+' - >user_id');
        console.log(uid+' - >uid');
        user_id=id;
        u_name=name;
    }
</script>

 

c#部分

使用了CsharpJson

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Net.Sockets;
using CsharpJson;
using System.Threading;



namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        bool b = false;
        IPAddress ip = IPAddress.Parse("192.168.1.85");
        Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        public Form1()
        {
            InitializeComponent();
            Control.CheckForIllegalCrossThreadCalls = false;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
            try
            {
                clientSocket.Connect(new IPEndPoint(ip, 8080)); //配置服务器IP与端口
                txt_msg.AppendText("连接服务器成功\n");
                Thread thread = new Thread(start);
                thread.Start();
                JsonObject obj = new JsonObject();
                obj.Add("type", "login");
                obj.Add("name", "c#");
                obj.Add("uid", 123);
                JsonDocument doc1 = new JsonDocument();
                doc1.Object = obj;
                string val = doc1.ToJson();
                clientSocket.Send(Encoding.Default.GetBytes(val));
                clientSocket.Send(Encoding.Default.GetBytes(val));
            }
            catch
            {
                txt_msg.AppendText("连接服务器失败\n");
                return;
            }
        }
        private void start()
        {
            int receiveLength = 0;
            while (true)
            {
                try
                {
                    byte[] result = new byte[1024];
                    receiveLength = clientSocket.Receive(result);
                    
                    if (receiveLength == 0)
                    {
                        continue;
                    }

                    JsonDocument doc = JsonDocument.FromString(Encoding.Default.GetString(result, 2, receiveLength));
                    
                    if (doc.IsObject())
                    {
                        
                        JsonObject jsobj = doc.Object;
                        
                        if (jsobj["type"].ToString()== "system")
                        {
                            string msg = "系统消息:";

                            if (jsobj["from"].ToString()== "login")
                            {
                                if (jsobj["content"].ToString() != "ok")
                                {
                                    txt_msg.AppendText(msg+"登录失败,可能由用户名或ID不可用" +"\n");
                                }
                                else
                                {
                                    
                                    this.txt_msg.Invoke(new Action(() =>
                                    {
                                        txt_msg.AppendText(msg + "登录成功" + "\n");
                                        txt_msg.AppendText(msg + "当前在线人数 " + jsobj["user_list_count"].ToInt() + "人\n");
                                        txt_msg.AppendText(msg + jsobj["user_list"].ToArray() + "人\n");
                                        var a = jsobj["user_list"].ToArray();
                                        for(int i = 0; i< a.Count;i++)
                                        {
                                            var b = a[i].ToObject();
                                            switch (b["uid"].Valuetype)
                                            {
                                                case JsonType.STRING:
                                                     txt_msg.AppendText(b["uid"].ToString() + "" + "\n");
                                                    break;
                                                case JsonType.NUMBER:
                                                    txt_msg.AppendText(b["uid"].ToInt() + "" + "\n");
                                                    break;
                                            }
                                            
                                        }
                                        

                                        //jsobj["user_list"].ToArray();
                                    }));
                                }
                                
                            }

                        }
                        else
                        {
                            string msg = "";
                            if (jsobj["type"].ToString() == "user_msg")
                            {
                                if (jsobj["msg_type"].Valuetype == JsonType.STRING)
                                {
                                    msg = unicode(jsobj["from"].ToString()) + " : ";
                                }
                                else
                                {
                                    msg = jsobj["from"].ToInt() + " : ";
                                }
                                if (jsobj["msg_type"].ToString()=="txt")
                                {
                                    if (jsobj["msg_type"].Valuetype == JsonType.STRING)
                                    {
                                        msg += unicode(jsobj["content"].ToString());
                                    }else if (jsobj["msg_type"].Valuetype == JsonType.NUMBER)
                                    {
                                        msg += jsobj["content"].ToString();
                                    }
                                    
                                }
                            }
                            txt_msg.AppendText(msg + "\r\n");
                        }
                        
                    }
                    else
                    {
                        Console.WriteLine(Encoding.Default.GetString(result, 2, receiveLength-2) + "\n");
                        //clientSocket.Send(buffer);
                    }
                }
               catch (Exception e)
                {
                    txt_msg.AppendText("与服务端断开连接\n");
                    break;
                }  
                //txt_msg.AppendText("接收服务器消息:{0}", Encoding.ASCII.GetString(result, 0, receiveLength));
            }
        }

        private void upui()
        {
            txt_msg.Text = DateTime.Now.ToLongTimeString();  //为同一线程则直接刷新label1
        }
        private string unicode (string str)
        {
            //UNICODE字符转为中文

            //str = "//u4e2d//u6587";
            string outStr = "";
            if (!string.IsNullOrEmpty(str))
            {
                string[] strlist = str.Replace("\\", "").Split('u');
                try
                {
                    for (int i = 1; i < strlist.Length; i++)
                    {
                        //将unicode字符转为10进制整数,然后转为char中文字符 
                        outStr += (char)int.Parse(strlist[i], System.Globalization.NumberStyles.HexNumber);
                    }
                }
                catch (FormatException ex)
                {
                    outStr = ex.Message;
                }
            }
            return outStr;
        }

        private void btn_sen_Click(object sender, EventArgs e)
        {
            //JsonObject obj = new JsonObject();
            //obj.Add("type", "login");
            //obj.Add("name", "c#");
            //obj.Add("uid", 121235673);
            //JsonDocument doc1 = new JsonDocument();
            //doc1.Object = obj;
            //string val = doc1.ToJson();
            //clientSocket.Send(Encoding.Default.GetBytes(val));
        }
    }
}

 


一只大萝北 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:[即时通讯]使用php写服务端,html和c#winfrom写客户端[弃坑中]
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址