搭建node.js 去node官网下载安装环境。
# 安装nodejs
```
node --version
v10.15.1
npm --version
6.4.1
```
# 生成配置文件
```
回到自己的项目目录里面
cd E:phpStudyWWWh1901 521game
npm init 执行该命令会生成一个package.json文件
```
安装socket.io 插件
```
安装插件,并写到配置文件里面去
npm install socket.io --save
npm install websocket.io --save
框架
npm install express --save
```
然后直到在自己本地服务器上面显示下面图上两个文件夹
一、我们建立一个登录 界面里面也有相关联的js。代码如下:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 6 <meta http-equiv="X-UA-Compatible" content="ie=edge"> 7 <title>登录页面</title> 8 <style> 9 *{ 10 padding: 0; 11 margin: 0; 12 } 13 .box{ 14 padding-top: 100px; 15 margin: auto; 16 } 17 h1{ 18 text-align: center; 19 font-weight: normal; 20 } 21 p{ 22 margin: auto; 23 text-align: center; 24 margin: 20px 0px; 25 } 26 p input{ 27 width: 230px; 28 height: 35px; 29 margin: auto; 30 text-align: center; 31 } 32 button{ 33 width: 230px; 34 height: 45px; 35 margin: auto; 36 background: skyblue; 37 color: white; 38 line-height: 45px; 39 display: block; 40 border-radius: 5px; 41 } 42 </style> 43 </head> 44 <body> 45 <div class="box"> 46 <form id="login"> 47 <h1>登录界面</h1> 48 <p><input type="text" name="username" class="username" id="username" placeholder="用户名" required /></p> 49 <button class="btn">登录</button> 50 </form> 51 </div> 52 </body> 53 </html> 54 <script src="./socket.io.js"></script> 55 <script src="./jquery-1.7.2.min.js"></script> 56 <script> 57 58 var ws = io.connect("http://localhost:3000"); 59 //接收服务器的结果 是主动的 60 61 ws.on("clientUser",function(obj){ 62 if(obj.res) 63 { 64 alert(`${obj.msg}已经存在了,请重新输入`); 65 $("#username").val(""); 66 $("#username").focus(); 67 return false; 68 }else{ 69 //跳转默然首页 70 console.log('用户已经注册'); 71 } 72 73 }); 74 75 $("#login").submit(function(){ 76 var username = $.trim($("#username").val()); 77 78 if(!username) 79 { 80 alert('昵称不能为空,请重新输入'); 81 return false; 82 }else{ 83 //执行所连接服务器上面的方法 84 ws.emit('join',username); 85 } 86 87 88 89 return false; 90 }); 91 </script>
二、我们使用的是Node.js,自己封装一个函数判断登录用户是否符合我们的检测。代码如下;
1 //服务器端 nodejs充当服务器 2 var express= require('express'), 3 io = require('socket.io'); 4 5 6 //创建一个应用 7 var app = express(); 8 9 //绑定应用的监听端口 10 var server = app.listen(3000,function(){ 11 console.log('服务已开启'); 12 }); 13 14 15 //用socket来监听服务 16 var ws = io.listen(server); 17 18 19 //给监听绑定动作 20 21 //新建方法 检测用户是否存在 22 var checkUser = function(username) 23 { 24 //ws.sockets.sockets 该对象里面放的是所有连接的客户端对象 25 for(var key in ws.sockets.sockets) 26 { 27 if(ws.sockets.sockets[key].username == username) 28 { 29 return true; //用户存在 30 } 31 } 32 return false; //用户不存在 33 } 34 35 //connection 连接事件 客户端连接到服务器 就会触发 36 //client 客户端对象 37 ws.on("connection",function(client){ 38 console.log('客户端已经连接到服务器'); 39 40 //给客户端弄一个接收数据的一个方法 41 client.on('join',function(username){ 42 43 if(checkUser(username)) 44 { 45 //说明存在了 调用会客户端 46 client.emit('clientUser',{res:true,msg:username}); 47 }else{ 48 //走进else说明这个人不存在,保存 49 //自定义对象属性 50 client.username = username; 51 console.log('该用户不存在'); 52 client.emit('clientUser',{res:false,msg:username}); 53 } 54 55 }); 56 })
})
三、我们这里也还要引进一个php文件,代码如下:
1 <?php 2 3 /** 4 * 聊天室服务器 websocket 专用 5 */ 6 class Server_socket 7 { 8 private $socket; 9 private $accept = []; 10 private $hands = []; 11 function __construct($host, $port, $max) 12 { 13 //创建一个socket连接,并且设置端口和地址,最大连接数 14 $this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); 15 socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, TRUE); 16 socket_bind($this->socket, $host,$port); 17 socket_listen($this->socket,$max); 18 print_r($this->socket); 19 } 20 21 public function start() 22 { 23 $i = 0; 24 while (true) { 25 26 $cycle = $this->accept; 27 $cycle[] = $this->socket; 28 socket_select($cycle, $write, $except, null); 29 30 foreach ($cycle as $sock) { 31 if ($sock == $this->socket) { 32 $this->accept[] = socket_accept($sock); 33 $arr = array_keys($this->accept); 34 $key = end($arr); 35 $this->hands[$key] = false; 36 }else{ 37 $length = socket_recv($sock, $buffer, 204800, null); 38 $key = array_search($sock, $this->accept); 39 if (!$this->hands[$key]) { 40 $this->dohandshake($sock,$buffer,$key); 41 }else if($length < 1){ 42 $this->close($sock); 43 }else{ 44 //接收从客户端发送的内容 解码 45 $data = $this->decode($buffer); 46 print_r(" This is the data received from client,".$data); 47 //服务器端的内容 编码 48 //$data = "This is the data sent by server".$i.", so smart"; 49 $data = $this->encode($data); 50 print_r($data); 51 //将信息传递给从机 52 foreach ($this->accept as $client) { 53 socket_write($client,$data ,strlen($data)); 54 } 55 $i++; 56 } 57 } 58 } 59 sleep(1); 60 } 61 }/* end of start*/ 62 63 /** 64 * 首次与客户端握手 65 */ 66 public function dohandshake($sock, $data, $key) { 67 if (preg_match("/Sec-WebSocket-Key: (.*) /", $data, $match)) { 68 $response = base64_encode(sha1($match[1] . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11', true)); 69 $upgrade = "HTTP/1.1 101 Switching Protocol " . 70 "Upgrade: websocket " . 71 "Connection: Upgrade " . 72 "Sec-WebSocket-Accept: " . $response . " "; 73 socket_write($sock, $upgrade, strlen($upgrade)); 74 $this->hands[$key] = true; 75 } 76 }/*dohandshake*/ 77 78 /** 79 * 关闭一个客户端连接 80 */ 81 public function close($sock) { 82 $key = array_search($sock, $this->accept); 83 socket_close($sock); 84 unset($this->accept[$key]); 85 unset($this->hands[$key]); 86 } 87 88 /** 89 * 字符解码 90 */ 91 public function decode($buffer) { 92 $len = $masks = $data = $decoded = null; 93 $len = ord($buffer[1]) & 127; 94 if ($len === 126) { 95 $masks = substr($buffer, 4, 4); 96 $data = substr($buffer, 8); 97 } 98 else if ($len === 127) { 99 $masks = substr($buffer, 10, 4); 100 $data = substr($buffer, 14); 101 } 102 else { 103 $masks = substr($buffer, 2, 4); 104 $data = substr($buffer, 6); 105 } 106 for ($index = 0; $index < strlen($data); $index++) { 107 $decoded .= $data[$index] ^ $masks[$index % 4]; 108 } 109 return $decoded; 110 } 111 112 /** 113 * 字符编码 114 */ 115 public function encode($buffer) { 116 $length = strlen($buffer); 117 if($length <= 125) { 118 return "x81".chr($length).$buffer; 119 } else if($length <= 65535) { 120 return "x81".chr(126).pack("n", $length).$buffer; 121 } else { 122 return "x81".char(127).pack("xxxxN", $length).$buffer; 123 } 124 } 125 126 }/* end of class Server_socket*/ 127 128 129 130 // 在执行该脚本的时候一定要注意是服务器要开启对应环境扩展 131 // php开启这个扩展 php_sockets 132 133 //要用命令行 php 134 // 135 136 // cd E:phpStudyphpphp-5.5.38 137 // E: 138 // php.exe E:phpStudyWWWh1901 521gameserver.php 139 140 //实例化 141 $server_socket = new Server_socket('127.0.0.1',9000,20); 142 $server_socket->start(); sleep(2); 143 ?>
四、实现效果如下:
1、
2、
具体开启node.js 服务器的关机键步骤:
①要在本地电脑服务器上的相对文件路径,因为我这里本地用的是phpStudy,所以如果不一样的话还要找其他参考方法
②:然后到命令符界面开启我们自己搭建的服务器,如下: