zoukankan      html  css  js  c++  java
  • websocket实现五子棋联机对战

    GoBang.html // 对弈的页面

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style>
                *{
                    padding: 0;margin: 0;
                }
                html,body{100%;height: 100%;}
                div{
                    text-align: center;
                }
                div button{
                    line-height: 50px;
                    font-size: 36px;
                }
                .canvas{
                    margin: 0 auto;
                }
            </style>
        </head>
        <body>
            <div class="canvas">
                <canvas id="gobang"></canvas>
            </div>
            
            <div>
                <button id="regret">悔棋</button>
                <button id="chessAgain">再来一局</button>
                <button id="goHome">返回大厅</button>
                <button id="getConnection">获取connection</button>
            </div>
        </body>
        <script type="text/javascript">
            var user,chessBoard,next;
            var gobang;
            if(sessionStorage.getItem("user")){
                user = JSON.parse(sessionStorage.getItem("user"));
                var qs = qs2obj(location.href);
                if(qs.player1==user.name){ // 玩家1
                    console.log("玩家1");
                    user.type = "player1";
                }else if(qs.player2==user.name){// 玩家2
                    console.log("玩家2");
                    user.type = "player2";
                }else{
                    console.log("观众");
                    user.type = "viewer";
                }
                user.roomId = qs.roomId;
            }else{
                location.href = "index.html";
            }
            var ws = new WebSocket("ws://10.100.106.114:9000");
            ws.onopen = function(e){
                sendUserMsg();
                
            }
            
            ws.onerror = function(e){
                console.log("链接服务器失败");
            }
            
            ws.onclose = function(e){
                console.log("链接断开");
            }
            
            ws.onmessage = function(e){
                console.log(e.data);
                var data = JSON.parse(e.data);
                switch(data.type){
                    case "baseMsg": 
                        
                        break;
                    case "chessBoard": 
                        chessBoard = data.data;
                        next = data.next;
                        
                        gobang.pieces = chessBoard;
                        gobang.active = next;
                        gobang.renderUi();
                        gobang.highLight(data.lastStep.x,data.lastStep.y,gobang.active);
                        gobang.hisStatus.push(gobang.deepClone(gobang.pieces));//历史记录(悔棋复盘功能使用)
                        gobang.getVictor();
                        break;
                    case "users":
                        
                        break;
                    default:;
                }
            }
            
            function sendUserMsg(){
                var msg = {};
                msg.type = "user";
                msg.data = user;
                ws.send(JSON.stringify(msg));
            }
            
            function sendChessBoard(next,chessBoard,x,y){
                var msg = {};
                msg.type = "chess";
                msg.next = next;// 下一个走棋的玩家
                msg.data = chessBoard;
                msg.roomId = user.roomId;
                msg.lastStep = {x:x,y:y};
                ws.send(JSON.stringify(msg));
            }
            
            function sendVictor(){
                var msg = {};
                msg.type = "victor";
                msg.data = victor;
                ws.send(JSON.stringify(msg));
            }
            
            function chessAgain(eventOrigin){
                var msg = {};
                msg.type = "again";
                msg.data = {eventOrigin:eventOrigin};
                ws.send(JSON.stringify(msg));
            }
            
            function getConnection(){
                var msg = {};
                msg.type = "connection";
                msg.data = {};
                ws.send(JSON.stringify(msg));
            }
            
            /**
             * @author web得胜
             * @param {String} url url地址栏
             * @return {Object}
             */
            function qs2obj(url) {
                var qs = url.split("?")[1];
                var arr = [];
                var res = {};
                if(!qs) {
                    // return res;
                } else {
                    arr = qs.split("&");
                    for(var i = 0, len = arr.length; i < len; i++) {
                        var key = arr[i].split("=")[0];
                        var val = arr[i].split("=")[1];
                        res[key] = decodeURIComponent(val);
                    }
                }
                return res;
            }
        </script>
        <script type="text/javascript">
            // 五子棋
    
    class Gobang {
        constructor(canvasId, rowCount = 16) {
            this.canvasId = canvasId;
            this.rowCount = rowCount;
            this.resetData();
        }
    
        // 渲染页面
        renderUi() {
            //清除之前的画布
            this.ctx.clearRect(0, 0, this.width, this.height);
    
            // 重绘画布
            this.drawChessBoard();
            this.drawPieces();
        }
    
        // 重置数据,再来一局
        resetData() {
            var body = document.documentElement || document.body;
            var minWidth = Math.min(body.clientWidth,body.clientHeight);
    
            // 属性
            this.pieces = []; // 棋子数组 二位数组[[],[]] 0——空  1——白  2——黑
            this.colCount = this.rowCount; // 列数
            this.cellWidth = minWidth / (this.rowCount); //每个格子的宽
            this.width = this.rowCount * this.cellWidth; // 棋盘的宽
            this.height = this.width; // 棋盘的高
            this.R = this.cellWidth * 0.4; // 棋子半径
            this.hisStatus = []; // 历史记录 history status
            this.active = 2; // 当前走棋方
            this.canvas = document.getElementById(this.canvasId); // canvas DOM
            this.ctx = this.canvas.getContext("2d"); // canvas环境
            this.victor = 0; // 胜利方
            this.canContinue = true; // 是否可以继续下棋(产生赢家以后不可以)
            this.myPositions = []; // 我方的推荐位置数组          格式:{x:5,y:6,weight:8}
            this.enemyPositions = []; // 敌方的推荐位置数组
    
            this.init();
        }
    
        // 初始化数据
        init() {
            this.initCanvas();
            this.initPiece();
            this.renderUi();
        }
        
        // 暂时给棋盘中间加一个黑棋
        first(){
            var center = Math.floor((this.rowCount+1)/2);
            this.pieces[center][center] = this.active;
            this.hisStatus[1] = this.deepClone(this.pieces);
            this.exchange();
        }
    
        // 设置棋盘的宽高
        initCanvas() {
            this.canvas.width = this.width;
            this.canvas.height = this.height;
        }
    
        // 初始化棋子
        initPiece() {
            var initPieces = [];
            for(let i = 0; i <= this.rowCount; i++) { //
                initPieces.push([]);
                for(let j = 0; j <= this.colCount; j++) { //
                    if(i==0 || j==0 || i==this.rowCount || j==this.rowCount){
                        initPieces[i].push(-1); // 不可以走的位置-1  空0 白1  黑2
                    }else{
                        initPieces[i].push(0); // 空0 白1  黑2
                    }
                }
            }
            this.pieces = this.deepClone(initPieces);
            this.hisStatus[0] = this.deepClone(initPieces);
            //this.first();
        }
        
        // 获取某个棋子的颜色     0——空  1——白  2——黑
        getColor (num){
            var res = "";
            switch(num){
                case 0:
                    res = "";
                    break;
                case 2:
                    res = "black";
                    break;
                case 1:
                    res = "white";
                    break;
                case -1:
                    res = "yellow";
                    break;
                default: 
                    res="red"; // 错误了
            }
            return res;
        }
    
        // 画棋盘
        drawChessBoard() {
            // 背景
            this.ctx.beginPath();
            this.ctx.rect(0, 0, this.width, this.height);
            this.ctx.closePath();
            this.ctx.fillStyle = "#0099CC";
            this.ctx.fill();
    
            // 画横线
            this.ctx.beginPath();
            for(let i = 0; i < this.rowCount; i++) {
                this.ctx.moveTo(0, this.cellWidth * i);
                this.ctx.lineTo(this.width, this.cellWidth * i);
            }
            this.ctx.strokeStyle = "#000000";
            this.ctx.stroke();
    
            // 画纵线
            this.ctx.beginPath();
            for(let i = 0; i < this.colCount; i++) {
                this.ctx.moveTo( this.cellWidth * i, 0);
                this.ctx.lineTo( this.cellWidth * i, this.height);
            }
            this.ctx.strokeStyle = "#000000";
            this.ctx.stroke();
        }
    
        // 画一个棋子
        drawDot(x, y, r, color) {
            this.ctx.beginPath();
            this.ctx.arc(x, y, r, 0, 2 * Math.PI);
            this.ctx.closePath();
    
            this.ctx.fillStyle = color;
            this.ctx.fill();
        }
    
        // 画所有的棋子
        drawPieces() {
            //console.log(this.pieces)
            for(var i = 0; i < this.pieces.length; i++) { // 边界线不让走棋
                for(let j=0; j < this.pieces[i].length;j++){
    //                if(this.pieces[i][j] == 1 || this.pieces[i][j] == 2){
                    if(this.pieces[i][j] !== 0){
                        var x = i * this.cellWidth;
                        var y = j * this.cellWidth;
    //                    var y = j * this.cellWidth - this.cellWidth/2;
                        this.drawDot(x,y,this.R,this.getColor(this.pieces[i][j]));
                    }
                }
            }
        }
        
        // 高亮最近走的棋子
        highLight(x,y,oneSide){
            var anotherSide = oneSide == 1 ? 2 :1;
            this.ctx.beginPath();
            this.ctx.moveTo(x * this.cellWidth - 10, y * this.cellWidth);
            this.ctx.lineTo(x * this.cellWidth + 10, y * this.cellWidth);
            this.ctx.moveTo(x * this.cellWidth, y * this.cellWidth - 10);
            this.ctx.lineTo(x * this.cellWidth, y * this.cellWidth + 10);
            this.ctx.closePath();
            this.ctx.strokeStyle = this.getColor(oneSide);
            
            this.ctx.stroke();
        }
        
        // 
        drawOnePiece(i,j){
            var x = i * this.cellWidth;
            var y = j * this.cellWidth;
            this.drawDot(x,y,this.R,this.getColor(this.active));
        }
        
        // 判断是否可以走这一步
        canGo(x, y) {
            if(this.canContinue === false){
                alert("游戏已结束");
                return false;
            }
            if(x==0 || y==0 || x==this.rowCount || y==this.rowCount){
                alert("边界上不可以走棋哦");
                return false;
            }
            if(this.pieces[x][y]==0){
                return true;
            }else {
                return false;
            }
        }
        
        // 切换角色(换着走棋)
        exchange(){
            this.active = this.active == 1 ? 2 : 1;
        }
    
        // 走一步棋
        goStep(x,y) {
            // 判断这一步是否可以走
            if(this.canGo(x,y)){
                console.log(this.active, user.type.slice(-1))
                if(this.active == user.type.slice(-1)){
                    this.pieces[x][y] = this.active;//添加棋子
                    
                    this.exchange();
                    sendChessBoard(this.active,this.pieces,x,y);
                    
                    
    //                this.renderUi();
    //                this.hisStatus.push(this.deepClone(this.pieces));//历史记录(悔棋复盘功能使用)
    //                this.getVictor();//这里有个坑,棋子还没有画上去,已经把输赢判断了????
    //                this.exchange();
                    
                    
                }else{
                    alert("轮到对方走棋了");
                }
                
                
                /*if(this.active == 1 && !this.victor){ // 白棋,机器人
                    this.helpRecommend(this.active);
                    console.log(this.myPositions,this.enemyPositions)
                    var p = this.bestPosition();
                    console.log(p);
                    this.pieces[p.x][p.y] = this.active;
                    this.drawOnePiece(p.x,p.y);
                    this.hisStatus.push(this.deepClone(this.pieces));//历史记录(悔棋复盘功能使用)
                    this.getVictor();
                    this.exchange();
    //                this.renderUi();
                }*/
            }else {
                // alert("这个位置已经被占领了,换个位置走吧");
            }
        }
        
        // 悔棋
        regret() {
            if(this.hisStatus.length<=1){
                console.log("当前不可以悔棋了");
                return;
            }
            this.hisStatus.pop();
            this.hisStatus.pop();
            this.pieces = this.deepClone(this.hisStatus[this.hisStatus.length-1]);
            // this.exchange();
            this.renderUi();
        }
        
        //
        helpRecommend(oneSide){
            var enemySide = oneSide == 1 ? 2 : 1;
            this.myPositions = [];
            this.enemyPositions = [];
            
            for(let i=1;i<this.rowCount;i++){
                
                for(let j=1;j<this.rowCount;j++){
                    
    //                 var arr = ["r","rd","d","ld","l","lt","t","rt"];
                    var arr = ["r","rd","d","ld"];
                    // 权重相关变量 forward  backward   center  double  null
                    var n2f1 = 0.2, // 两头空时 前面第一个空位置的权重
                        n2f2 = 0.1, // 两头空时 前面第二个空位置的权重
                        n2b1 = n2f1,
                        n2b2 = n2f2,
                        n1f1 = -0.1, // 一头空另一头是敌方或边界时  前面第一个空位置的权重
                        n1f2 = -0.2,
                        n1b1 = n1f1,
                        n1b2 = n1f2,
                        dn2c = 0.2, // 有两个片段时   两端都是空的时   中间位置的权重
                        dn2b1 = 0.1,// 有两个片段时   两端都是空的时   后方第一个位置的权重
                        dn2f1 = dn2b1,
                        dn1c = -0.1,
                        dn1b1 = -0.1,
                        dn1f1 = dn1b1;
                    
                    
                    
                    if(this.pieces[i][j]==oneSide){ // 我方
                        for(var d =0;d<arr.length;d++){
                            var count = 0;
                            count = this.directionCount(arr[d],oneSide,i,j);
                            var nd = this.nd(arr[d]);
                            var h = nd.h;
                            var v = nd.v;
                            
                            // 某个方向的末端的推荐权重  (权重暂时认为后方第一个位置和第二位位置一样) 两头空的+0.2  一端空的+0  两端都死的考虑能否凑5个子
                            if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
                                if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 末1空
                                    if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === 0){ //末2空
                                        this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+n2b1));
                                        this.sumWeight(this.myPositions,i+(count+1)*h,j+(count+1)*v,10**(count+n2b2));
                                    }else if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === oneSide){ // 末2己
                                        let count2 = this.directionCount(arr[d],oneSide,i+(count+1)*h,j+(count+1)*v);
                                        if(this.pieces[i+(count+1+count2)*h] && this.pieces[i+(count+1+count2)*h][j+(count+1+count2)*v] === 0){
                                            this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+count2+dn2c));
                                            this.sumWeight(this.myPositions,i+(count+1+count2)*h,j+(count+1+count2)*v,10**(count+count2+dn2b1));
                                        }else {
                                            this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+count2+dn1c));
                                        }
                                    }else { //末2敌或边界  
                                        this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+n1b1));
                                    }
                                }else { // 末1敌或边界   末1不可能是己方的
                                    // 末端没有推荐的位置
                                }
                            }else if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === oneSide){ // 前1己  这里已经计算过了,跳过逻辑
                                continue;
                            }else { // 前1 敌方或边界
                                if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 末1空
                                    if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === 0){ //末2空
                                        this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+n1b1));
                                        this.sumWeight(this.myPositions,i+(count+1)*h,j+(count+1)*v,10**(count+n1b2));
                                    }else if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === oneSide){ // 末2己
    //                                    this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+0.1));
                                        let count2 = this.directionCount(arr[d],oneSide,i+(count+1)*h,j+(count+1)*v);
                                        if(this.pieces[i+(count+1+count2)*h] && this.pieces[i+(count+1+count2)*h][j+(count+1+count2)*v] === 0){
                                            this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+count2+dn1c));
                                            this.sumWeight(this.myPositions,i+(count+1+count2)*h,j+(count+1+count2)*v,10**(count+count2+dn1b1));
                                        }else {// 两端是死的 中间要么是5要么就没意义
                                            if(count+1+count2 == 5){
                                                this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+count2+1));
                                            }else{
                                                this.sumWeight(this.myPositions,i+count*h,j+count*v,0);
                                                //console.log("中间凑不够5个,中间权重是0");
                                            }
                                        }
                                    }else { //末2敌或边界
                                        if(count==4){ // 只有四颗子的时候这个位置才有意义
                                            this.sumWeight(this.myPositions,i+count*h,j+count*v,10**(count+1));
                                        }
                                    }
                                }else { // 末1敌或边界   末1不可能是己方的
                                    // 走不了了
                                }
                            }
                            
                            // 某个方向的前端的推荐权重
                            if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 后1空
                                if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
                                    if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === 0){ //前2空
                                        this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+n2f1));
                                        this.sumWeight(this.myPositions,i-2*h,j-2*v,10**(count+n2f2));
                                    }else if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === oneSide){ // 前2己
    //                                    this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+0.3));
                                        let count2 = this.directionCount(this.reverseDirection(arr[d]),oneSide,i-2*h,j-2*v);
                                        if(this.pieces[i-(1+count2)*h] && this.pieces[i-(1+count2)*h][j-(1+count2)*v] === 0){
                                            this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+count2+dn2c));
                                            this.sumWeight(this.myPositions,i-(1+count2)*h,j-(1+count2)*v,10**(count+count2+dn2f1));
                                        }else {
                                            this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+count2+dn1c));
                                            this.sumWeight(this.myPositions,i-(1+count2)*h,j-(1+count2)*v,10**(count+count2+dn1f1));
                                        }
                                    }else { //前2敌或边界
                                        this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+n1f1));
                                    }
                                }else { // 前1敌或边界   前1不可能是己方的
                                    // 前端没有推荐的位置
                                }
                            }else if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === oneSide){ // 后1己  这里已经计算过了,跳过逻辑
                                continue;
                            }else { // 后1 敌方或边界
                                if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
                                    if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === 0){ //前2空
                                        this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+n1f1));
                                        this.sumWeight(this.myPositions,i-2*h,j-2*v,10**(count+n1f2));
                                    }else if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === oneSide){ // 前2己
                                        // this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+0.1));
                                        let count2 = this.directionCount(this.reverseDirection(arr[d]),oneSide,i-2*h,j-2*v);
                                        if(this.pieces[i-(1+count2)*h] && this.pieces[i-(1+count2)*h][j-(1+count2)*v] === 0){
                                            this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+count2+dn1c));
                                            this.sumWeight(this.myPositions,i-(1+count2)*h,j-(1+count2)*v,10**(count+count2+dn1f1));
                                        }else {
                                            if(count+1+count2 == 5){
                                                this.sumWeight(this.myPositions,i-1*h,j-1*v,10**(count+count2+1));
                                            }else{
                                                this.sumWeight(this.myPositions,i-1*h,j-1*v,0);
                                                //console.log("中间凑不够5个,中间权重是0");
                                            }
                                        }
                                    }else { //前2敌或边界
                                        if(count==4){ // 只有四颗子的时候这个位置才有意义
                                            this.sumWeight(this.myPositions,i-2*h,j-2*v,10**(count+1));
                                        }
                                    }
                                }else { // 前1敌或边界  前1不可能是己方的
                                    // 前后都是敌,推荐个锤子
                                }
                            }
                        }
                    }else if(this.pieces[i][j]==enemySide){ // 敌方
                        for(var d =0;d<arr.length;d++){
                            var count = 0;
                            count = this.directionCount(arr[d],enemySide,i,j);
                            var nd = this.nd(arr[d]);
                            var h = nd.h;
                            var v = nd.v;
                            // 某个方向的末端的推荐权重
                            if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
                                if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 末1空
                                    if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === 0){ //末2空
                                        this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+n2b1));
                                        this.sumWeight(this.enemyPositions,i+(count+1)*h,j+(count+1)*v,10**(count+n2b2));
                                    }else if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === enemySide){ // 末2己
                                        let count2 = this.directionCount(arr[d],enemySide,i+(count+1)*h,j+(count+1)*v);
                                        if(this.pieces[i+(count+1+count2)*h] && this.pieces[i+(count+1+count2)*h][j+(count+1+count2)*v] === 0){
                                            this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+count2+dn2c));
                                            this.sumWeight(this.enemyPositions,i+(count+1+count2)*h,j+(count+1+count2)*v,10**(count+count2+dn2b1));
                                        }else {
                                            this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+count2+dn1c));
                                        }
                                        // this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+0.3));
                                    }else { //末2敌或边界  
                                        this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+n1b1));
                                    }
                                }else { // 末1敌或边界   末1不可能是己方的
                                    // 末端没有推荐的位置
                                }
                            }else if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === enemySide){ // 前1己  这里已经计算过了,跳过逻辑
                                continue;
                            }else { // 前1 敌方或边界
                                if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 末1空
                                    if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === 0){ //末2空
                                        this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+n1b1));
                                        this.sumWeight(this.enemyPositions,i+(count+1)*h,j+(count+1)*v,10**(count+n1b2));
                                    }else if(this.pieces[i+(count+1)*h] && this.pieces[i+(count+1)*h][j+(count+1)*v] === enemySide){ // 末2己
                                        //this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+0.1));
                                        let count2 = this.directionCount(arr[d],enemySide,i+(count+1)*h,j+(count+1)*v);
                                        if(this.pieces[i+(count+1+count2)*h] && this.pieces[i+(count+1+count2)*h][j+(count+1+count2)*v] === 0){
                                            this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+count2+dn1c));
                                            this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+count2+dn1f1));
                                        }else {// 两端是死的,看中间够5个不
                                            if(count+1+count2 == 5){
                                                this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+count2+1));
                                            }else{
                                                this.sumWeight(this.enemyPositions,i+count*h,j+count*v,0);
                                                //console.log("中间凑不够5个,中间权重是0");
                                            }
                                        }
                                    }else { //末2敌或边界
                                        if(count==4){ // 只有四颗子的时候这个位置才有意义
                                            this.sumWeight(this.enemyPositions,i+count*h,j+count*v,10**(count+1));
                                        }
                                    }
                                }else { // 末1敌或边界   末1不可能是己方的
                                    // 走不了了
                                }
                            }
                            
                            // 某个方向的前端的推荐权重
                            if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === 0){ // 后1空
                                if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
                                    if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === 0){ //前2空
                                        this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+n2f1));
                                        this.sumWeight(this.enemyPositions,i-2*h,j-2*v,10**(count+n2f2));
                                    }else if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === enemySide){ // 前2己
                                        // this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+0.3));
                                        let count2 = this.directionCount(this.reverseDirection(arr[d]),enemySide,i-2*h,j-2*v);
                                        if(this.pieces[i-(1+count2)*h] && this.pieces[i-(1+count2)*h][j-(1+count2)*v] === 0){
                                            this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+count2+dn2c));
                                            this.sumWeight(this.enemyPositions,i-(1+count2)*h,j-(1+count2)*v,10**(count+count2+dn2f1));
                                        }else {
                                            this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+count2+dn1c));
                                        }
                                    }else { //前2敌或边界
                                        this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+dn1c));
                                    }
                                }else { // 前1敌或边界   前1不可能是己方的
                                    // 前端没有推荐的位置
                                }
                            }else if(this.pieces[i+count*h] && this.pieces[i+count*h][j+count*v] === enemySide){ // 后1己  这里已经计算过了,跳过逻辑
                                continue;
                            }else { // 后1 敌方或边界
                                if(this.pieces[i-1*h] && this.pieces[i-1*h][j-1*v] === 0){ // 前1空
                                    if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === 0){ //前2空
                                        this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+n1f1));
                                        this.sumWeight(this.enemyPositions,i-2*h,j-2*v,10**(count+n1f2));
                                    }else if(this.pieces[i-2*h] && this.pieces[i-2*h][j-2*v] === enemySide){ // 前2己
                                        // this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+0.1));
                                        let count2 = this.directionCount(this.reverseDirection(arr[d]),enemySide,i-2*h,j-2*v);
                                        if(this.pieces[i-(1+count2)*h] && this.pieces[i-(1+count2)*h][j-(1+count2)*v] === 0){
                                            this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+count2+dn1c));
                                            this.sumWeight(this.enemyPositions,i-(1+count2)*h,j-(1+count2)*v,10**(count+count2+dn1f1));
                                        }else { // 前后是死的
                                            if(count+1+count2 == 5){
                                                this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+count2+1));
                                            }else{
                                                this.sumWeight(this.enemyPositions,i-1*h,j-1*v,0);
                                                //console.log("中间凑不够5个,中间权重是0");
                                            }
                                        }
                                    }else { //前2敌或边界
                                        if(count==4){ // 只有四颗子的时候这个位置才有意义
                                            this.sumWeight(this.enemyPositions,i-1*h,j-1*v,10**(count+1));
                                        }
                                    }
                                }else { // 前1敌或边界  前1不可能是己方的
                                    // 前后都是敌,推荐个锤子
                                }
                            }
                            
                        }
                    }
                }
            }
        }
        
        reverseDirection(direction){
            var rd = "";
            switch(direction){
                case "r":
                    rd = "l";break;
                case "rd":
                    rd = "lt";break;
                case "d":
                    rd = "t";break;
                case "ld":
                    rd = "rt";break;
                case "l":
                    rd = "r";break;
                case "lt":
                    rd = "rd";break;
                case "t":
                    rd = "d";break;
                case "rt":
                    rd = "ld";break;
                default: console.error("输入方向不对,无法反转");     
            }
            return rd;
        }
        
        // 方向数字化numberDirection r(1,0) rd(1,1) ld(-1,1)
        nd(direction){
            var res = {h:0,v:0}; // h horizontal v vertical
            switch(direction){
                case "r":
                    res.h = 1;
                    res.v = 0;
                    break;
                case "rd":
                    res.h = 1;
                    res.v = 1;
                    break;
                case "d":
                    res.h = 0;
                    res.v = 1;
                    break;
                case "ld":
                    res.h = -1;
                    res.v = 1;
                    break;
                case "l":
                    res.h = -1;
                    res.v = 0;
                    break;
                case "lt":
                    res.h = -1;
                    res.v = -1;
                    break;
                case "t":
                    res.h = 0;
                    res.v = -1;
                    break;
                case "rt":
                    res.h = 1;
                    res.v = -1;
                    break;
                default: console.error("方向输入有误");
            }
            return res;
        }
        
        // 合并同一个位置的权重
        sumWeight(arr,x,y,weight){
            var index = -1;
            for(let i=0,len=arr.length;i<len;i++){
                if(arr[i].x==x && arr[i].y==y){
                    index = i;
                    break;
                }
            }
            if(index!=-1){ // 如果已存在则权重相加
                arr[index].weight += weight;
            }else{ // 如果不存在则添加一条
                arr.push({x,y,weight});
            }
        }
        
        // 从推荐位置中找出最佳位置  权重最大的位置
        bestPosition (){
            var myMax=0,myP={},myArr=[];
            for(let i=0,len=this.myPositions.length;i<len;i++){
                if(this.myPositions[i].weight>myMax){
                    myMax = this.myPositions[i].weight;
                    myP.x = this.myPositions[i].x;
                    myP.y = this.myPositions[i].y;
                }
            }
            var enemyMax = 0, enemyP = {}, enemyArr = [];
            for(let i=0,len=this.enemyPositions.length;i<len;i++){
                if(this.enemyPositions[i].weight>enemyMax){
                    enemyMax = this.enemyPositions[i].weight;
                    enemyP.x = this.enemyPositions[i].x;
                    enemyP.y = this.enemyPositions[i].y;
                }
            }
    //        console.log(this.myPositions,this.ememyPositions);
            // console.log("敌方权重最大:"+enemyMax,"我方权重最大:"+myMax);
            
            for(let i=0,len=this.myPositions.length;i<len;i++){
                if(this.myPositions[i]==myMax){
                    myArr.push(this.deepClone(this.myPositions[i]));
                }
            }
            for(let i=0,len=this.enemyPositions.length;i<len;i++){
                if(this.enemyPositions[i]==enemyMax){
                    enemyArr.push(this.deepClone(this.enemyPositions[i]));
                }
            }
            if(enemyMax>myMax){
                // 敌方权重最大的地方(有相同位置时,谋求自己的大权重位置)
                var myMaxW = 0; // 我方在敌方最有位置处的最佳权重
                var recommedP = enemyP;
                for(let i=0, len=enemyArr.length;i<len;i++){
                    for(let j=0,len1=this.myPositions.length;j<len1;j++){
                        if(this.myPositions[j].x==enemyArr[i].x && this.myPositions[j].y==enemyArr[i].y){
                            if(this.myPositions[j].weight>myMaxW){
                                myMaxW = this.myPositions[j].weight;
                                recommedP.x = this.myPositions[j].x;
                                recommedP.y = this.myPositions[j].y;
                            }
                        }
                    }
                }
                return recommedP;
            }else {
                // 我方权重最大的地方(有相同位置时,占据敌方的相对大权重位置)
                var enemyMaxW = 0; // 我方在敌方最有位置处的最佳权重
                var recommedP = myP;
                for(let i=0, len=myArr.length;i<len;i++){
                    for(let j=0,len1=this.enemyPositions.length;j<len1;j++){
                        if(this.enemyPositions[j].x==myArr[i].x && this.enemyPositions[j].y==myArr[i].y){
                            if(this.enemyPositions[j].weight>enemyMaxW){
                                enemyMaxW = this.enemyPositions[j].weight;
                                recommedP.x = this.enemyPositions[j].x;
                                recommedP.y = this.enemyPositions[j].y;
                            }
                        }
                    }
                }
                return recommedP;
            }
        }
        
        // 获取赢家
        getWinner(){
            switch(this.victor){
                case 0:
                    console.log("还没产生赢家");break;
                case 1: 
                    this.canContinue = false;
                    setTimeout(()=>{alert("白棋赢");},30);
                    break;
                case 2:
                    this.canContinue = false;
                    setTimeout(()=>{alert("黑棋赢");},30);
                    break;
                default:;
            }
        }
    
        // 判断输赢
        getVictor() { //1.找到一个当前棋子,2.判断它的右、右下、下、左下四个方向是否连成5个棋子
            var arr = ["r","rd","d","ld"];
            for(var i=1;i<this.pieces.length;i++){
                for(var j=1;j<this.pieces[i].length;j++){
                    if(this.pieces[i][j] == 1){
                        for(let k = 0;k<arr.length;k++){
                            if(this.directionCount(arr[k],1,i,j) == 5){// 右r 下d 左l 上t 
                                this.victor = 1;
                                this.getWinner();
                                return;
                            }
                        }
                    }else{
                        for(let k = 0;k<arr.length;k++){
                            if(this.directionCount(arr[k],2,i,j) == 5){// 右r 下d 左l 上t 
                                this.victor = 2;
                                this.getWinner();
                                return;
                            }
                        }
                    }
                }
            }
            
    
        }
        
        // 此函数替代了原来的 directionCount
        directionCount(direction,oneSide,i,j){
            var count = 0;
            var nd = this.nd(direction);
            if(this.pieces[i][j] == oneSide){
                count = 1;
                for(let k=1;k<5;k++){
                    if(this.pieces[i+k*nd.h] && this.pieces[i+k*nd.h][j+k*nd.v] === oneSide){
                        count++;
                        continue;
                    }else {
                        break;
                    }
                }
            }
            return count;
        }
        
        // 深拷贝
        deepClone(values) {
            var copy;
    
            // Handle the 3 simple types, and null or undefined
            if(null == values || "object" != typeof values) return values;
    
            // Handle Date
            if(values instanceof Date) {
                copy = new Date();
                copy.setTime(values.getTime());
                return copy;
            }
    
            // Handle Array
            if(values instanceof Array) {
                copy = [];
                for(var i = 0, len = values.length; i < len; i++) {
                    copy[i] = this.deepClone(values[i]);
                }
                return copy;
            }
    
            // Handle Object
            if(values instanceof Object) {
                copy = {};
                for(var attr in values) {
                    if(values.hasOwnProperty(attr)) copy[attr] = this.deepClone(values[attr]);
                }
                return copy;
            }
    
            throw new Error("Unable to copy values! Its type isn't supported.");
        }
    }
        </script>
        <script type="text/javascript">
            gobang = new Gobang("gobang");
            var canvas = document.getElementById("gobang");
            console.log(canvas.getBoundingClientRect());
            var offset;
            canvas.addEventListener("click",function(e){
                offset = canvas.getBoundingClientRect();
                var x = Math.round((e.clientX - offset.left) / gobang.cellWidth);
                var y = Math.round((e.clientY - offset.top) / gobang.cellWidth);
                // console.log(x,y,"点击位置");
                
                // 走棋
                gobang.goStep(x,y);
            },false);
            document.getElementById("regret").addEventListener("click",()=>{
                gobang.regret();
            },false);
            document.getElementById("goHome").addEventListener("click",()=>{ // 关闭当前窗口
                window.opener=null;
                window.open('','_self');
                window.close();
            });
            document.getElementById("chessAgain").addEventListener("click",()=>{
                if(gobang.victor){
                    
                    gobang.resetData();
                }else{
                    alert("当前对弈结束后才可以重新开始~");
                }
            });
            
            document.getElementById("getConnection").addEventListener("click",()=>{
                 getConnection();
            });
        </script>
    </html>

    goBangServer.js // 对弈的服务

    var ws = require("nodejs-websocket");
    var users = [];
    var onlineCount = 0;
    
    var chessBoard = [];
    var next = 2;// 下一步走棋的人
    var lastStep = {}; // 上一步
    
    var IP = "10.100.106.114";
    var port = 9000;
    
    
    var server = ws.createServer(function(connection){
        
        var user;
        
        console.log("有新用户接入");
        onlineCount = server.connections.length;
        
        
        connection.on("text",function(str){
            console.log("接收到消息",str);
            var data = JSON.parse(str);
            if(data.type == "chess"){ // 走一步棋子
                chessBoard = data.data;
                next = data.next;
                lastStep = data.lastStep;
                broadCastChessBoard(data.roomId);
            }else if(data.type == "regret"){ // 悔棋
                
            }else if(data.type == "giveUp"){ // 认输
                
            }else if(data.type == "again"){ // 再来一局
                if(data.data.eventOrigin == "player1"){
                    var msg = {};
                    msg.type = "again";
                    server.connections.forEach(function(conn,index) {
                        connection.sendText(JSON.stringify(msg));
                    })
                }else if(data.data.eventOrigin == "player2"){
                    var msg = {};
                    msg.type = "again";
                    server.connections.forEach(function(conn,index) {
                        connection.sendText(JSON.stringify(msg));
                    })
                }else{
                    // continue;
                }
            }else if(data.type == "user"){ // 新用户接入
                user = data.data;
                user.sessionId = connection.headers['sec-websocket-key'];
                if(users.containUserName(user.name)){
                    var index = users.userIndex(user.name);
                    users[index] = user;
                }else{
                    users.push(user);
                }
                //broadCastChessBoard();
            }else{ // 未知类型
                
                server.connections.forEach(function(conn,index) {
                    // console.log(connection.headers['sec-websocket-key']);
                    // console.log(server.connections[index].headers['sec-websocket-key'])
                   // connection.sendText(JSON.stringify(server.connections[index]));
                })
            }
        });
        
        connection.on("error",function(err){
            console.log('遇到错误,详情:');
            console.log(err);
        });
        
        connection.on("close",function(code,reason){
            console.log("code closed", code);
            console.log("reason closed", reason);
            users.removeUser(user);
        });
        
    }).listen(port);
    
    
    Array.prototype.removeUser = function(user){
        for(let i=0;i<this.length;i++){
            //console.log(JSON.stringify(this[i]), JSON.stringify(user));
            if(JSON.stringify(this[i]) == JSON.stringify(user)){
                this.splice(i,1);
            }
        }
    }
    
    Array.prototype.containUserName = function(str) {
        for (var i = 0; i < this.length; i++) {
            if (this[i].name == str) {
                return true;
            }
        }
        return false;
    }
    
    Array.prototype.userIndex = function(str) {
        var index = -1;
        for (var i = 0; i < this.length; i++) {
            if (this[i].name == str) {
                index = i;
            }
        }
        return index;
    }
    
    function broadCastChessBoard(roomId){
        console.log("在线人数:"+server.connections.length);
        
        var msg = {};
        msg.type = "chessBoard";
        msg.data = chessBoard;
        msg.next = next;
        msg.lastStep = lastStep;
        console.log(users)
        users.forEach((user,index)=>{
            if(user.roomId == roomId){ //sessionId
                server.connections.forEach(function(connection,index) {
                    if(server.connections[index].headers['sec-websocket-key'] == user.sessionId){
                        connection.sendText(JSON.stringify(msg));
                    }
                })
            }
        })
        
    }
    //console.log(server);
    console.log("服务已搭建好,静候佳音;链接地址:ws://"+IP+":"+port);

    index.html // 选房间的页面

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <title></title>
            <style type="text/css">
                *{
                    padding: 0;
                    margin: 0;
                }
                .room{
                    width: 240px;
                    float: left;
                    height: 100px;
                    line-height: 100px;
                    border: 1px solid #e73480;
                    margin: 10px 10px;
                    display: flex;
                }
                .left,.right{
                    flex: 1;
                    width:80px;
                    text-align: center;
                    height: 100%;
                }
                .center{
                    flex: 1;
                    color: #006699;
                    width: 80px;
                    height: 100%;
                    text-align: center;
                }
            </style>
        </head>
        <body>
            <div class="wrapper">
                
            </div>
            <!--<div class="room" data-room="1">
                <span class="left">玩家1</span>
                <span class="center">桌子</span>
                <span class="right">玩家2</span>
            </div>-->
        </body>
        <script type="text/javascript">
            var user = {name:"",roomId: -1,type: "hangOut",chessing:false}; // 玩家当前角色——玩家(player)/观众(viewer)/游客(hangOut)
            if(sessionStorage.getItem("user")){
                user = JSON.parse(sessionStorage.getItem("user"));
            }
            while(!user.name){
                user.name =  window.prompt("请给你起一个响亮的名字","玩家姓名");
                sessionStorage.setItem("user",JSON.stringify(user));
            }
            
            var rooms = []; // 每个房间有房间号id,玩家1{name:赵德升},玩家2,观众[{name:solid}],棋盘chessBoard
            var roomCount = 0;
            var users = [];
            var left, right, center;
            
            
            var wrapper = getClass("wrapper")[0];
            function initUi(){
                var htmlStr = "";
                for(let i=0;i<roomCount;i++){
                    htmlStr += '<div class="room" data-room='+i+'>'+
                                '<span class="left">'+"玩家1"+'</span>'+
                                '<span class="center">桌子'+i+'</span>'+
                                '<span class="right">玩家2</span>'+
                            '</div>';
                }
                wrapper.innerHTML = htmlStr;
                
                for(let i=0;i<roomCount;i++){
                    rooms[i] = {};
                    rooms[i].id = i;
                    rooms[i].player1 = {};
                    rooms[i].player2 = {};
                    rooms[i].viewers = [];
                    rooms[i].chessBoard = [];
                }
                
                left = getClass("left");
                for(let i=0;i<left.length;i++){
                    left[i].onclick = function(){
                        if(!rooms[i].player1.name){
                            clearUsers();
                            user.roomId = i;
                            user.type = "player1";
                            rooms[i].player1 = user;
                            this.innerText = user.name;
                            sendUserMsg();
                            goToChess(i);
                        }else{
                            alert("此位置已经有人了");
                        }
                    }
                }
                
                right = getClass("right");
                for(let i=0;i<right.length;i++){
                    right[i].onclick = function(){
                        if(!rooms[i].player2.name){
                            clearUsers();
                            user.roomId = i;
                            user.type = "player2";
                            rooms[i].player2 = user;
                            this.innerText = user.name;
                            sendUserMsg();
                            goToChess(i);
                        }else{
                            alert("此位置已经有人了");
                        }
                    }
                }
                
                center = getClass("center");
                for(let i=0;i<center.length;i++){
                    center[i].onclick = function(){
                        if(rooms[i].player1.name && rooms[i].player2.name){
                            clearUsers();
                            user.roomId = i;
                            user.type = "viewer";
                            rooms[i].player1 = user;
                            sendUserMsg();
                            goToChess(i);
                        }else{
                            alert("这里人手不够,不可以观战哦~");
                        }
                    }
                }
            }
            
            function getClass(className){
                return document.getElementsByClassName(className);
            }
            
            function goToChess(roomId){
                if(rooms[roomId].player1.name && rooms[roomId].player2.name){
                    if(user.roomId == roomId && !user.chessing){
                        user.chessing = true;
                        window.open("GoBang.html?roomId="+roomId+"&player1="+rooms[roomId].player1.name+"&player2="+rooms[roomId].player2.name);
                    }
                }
            }
            
            function clearUsers(){
                for(let i = 0;i<left.length;i++){
                    left[i].innerText = "玩家1";
                }
                for(let i = 0;i<right.length;i++){
                    right[i].innerText = "玩家2";
                }
                for(let i=0;i<roomCount;i++){
                    rooms[i] = {};
                    rooms[i].id = i;
                    rooms[i].player1 = {};
                    rooms[i].player2 = {};
                    rooms[i].viewers = [];
                    rooms[i].chessBoard = [];
                }
            }
                
            function showUsers(){
                clearUsers();
                for(let i=0;i<users.length;i++){
                    console.log(users)
                    if(users[i].roomId>=0){
                        if(users[i].type == "player1"){//玩家1
                            rooms[users[i].roomId].player1 = users[i];
                            left[users[i].roomId].innerText = users[i].name;
                        }else if(users[i].type == "player2"){//玩家2
                            rooms[users[i].roomId].player2 = users[i];
                            right[users[i].roomId].innerText = users[i].name;
                        }else{//观众
                            
                        }
                        
                        goToChess(users[i].roomId);
                    }
                }
            }
            
            /*left.map((val,index,arr)=>{
                val.onclick = function(){
                    var val = window.prompt("请输入你的姓名"); 
                    val.innerText = val;
                }
            });*/
            
            var ws = new WebSocket('ws://10.100.106.114:8080');
            ws.onopen = function(e){
                sendUserMsg();
                
            }
            
            ws.onerror = function(e){
                console.log("链接服务器失败");
                user.chessing = false;
            }
            
            ws.onclose = function(e){
                console.log("链接断开");
                user.chessing = false;
            }
            
            ws.onmessage = function(e){
                console.log(e.data);
                var data = JSON.parse(e.data);
                switch(data.type){
                    case "baseMsg": 
                        roomCount = data.data.roomCount;
                        initUi();
                        break;
                    case "usersMsg": 
                        users = data.data;
                        showUsers();
                        break;
                    case "users":
                        
                        break;
                    default:;
                }
            }
            
            function sendUserMsg(){
                var msg = {};
                msg.type = "user";
                msg.data = user;
                ws.send(JSON.stringify(msg));
            }
            
            function recieveMsg(d){
                console.log(d);
            }
        </script>
    </html>

    server.js // 创建房间的服务

    var ws = require("nodejs-websocket");
    //console.log(ws);
    var users = [];
    var onlineCount = 0;
    var roomCount = 30;
    var ip = "10.100.106.114";
    var port = 9009;
    
    var server = ws.createServer(function(connection){
        var user;
        
        console.log("有新用户接入");
        onlineCount++;
        
        connection.on("text",function(str){
            console.log("接收到消息",str);
            //connection.sendText("把你的消息再还给你——"+str);
            var data = JSON.parse(str);
            if(data.type == "user"){
                user = data.data;
                // server.connections.user = user;
                if(users.containUserName(user.name)){
                    var index = users.userIndex(user.name);
                    users[index] = user;
                }else{
                    users.push(user);
                }
                
                //broadCastUsers(connection,JSON.stringify(users));
                broadCastUsers();
            }
        });
        
        connection.on("error",function(err){
            console.log('handle err');
            console.log(err);
        });
        
        connection.on("close",function(code,reason){
            console.log("code closed", code);
            console.log("reason closed", reason);
            users.removeUser(user);
        });
        
        var msg = {};
        msg.type = "baseMsg";
        msg.data = {"roomCount":roomCount};
        connection.send(JSON.stringify(msg));
        //connection.send("服务器已和你建立链接");
        
    }).listen(port);
    
    function broadCast(connection,roomId,str){
        for(let i=0;i<connection.lenth;i++){
            if(connection[i].user.roomId == roomId){
                connection[i].senText("广播消息——"+str);
            }
        }
    }
    
    Array.prototype.removeUser = function(user){
        for(let i=0;i<this.length;i++){
            //console.log(JSON.stringify(this[i]), JSON.stringify(user));
            if(JSON.stringify(this[i]) == JSON.stringify(user)){
                this.splice(i,1);
            }
        }
    }
    
    Array.prototype.containUserName = function(str) {
        for (var i = 0; i < this.length; i++) {
            if (this[i].name == str) {
                return true;
            }
        }
        return false;
    }
    
    Array.prototype.userIndex = function(str) {
        var index = -1;
        for (var i = 0; i < this.length; i++) {
            if (this[i].name == str) {
                index = i;
            }
        }
        return index;
    }
    
    function broadCastUsers(){
        console.log(server.connections.length);
        var msg = {};
        msg.type = "usersMsg";
        msg.data = users;
        server.connections.forEach(function(connection,index) {
            //console.log(index);
            connection.sendText(JSON.stringify(msg));
        })
    }
    //console.log(server);
    console.log("服务已搭建好,静候佳音;链接地址:ws://"+ip+":"+port);

    安装依赖nodejs-websocket,启动那两个服务js,把代码放在服务器上或者用HBuilder打开就可以用了

  • 相关阅读:
    读《大道至简》第二章有感
    《大道至简》读后感
    JAVA课后作业
    大道至简第三章观后感
    JAVA作业之两数的加减乘除
    JAVA作业之动手动脑
    第一次Java实验
    大道至简第二章观后感
    大道至简第一章观后感
    Django__admin的配置
  • 原文地址:https://www.cnblogs.com/zhaodesheng/p/10063745.html
Copyright © 2011-2022 走看看