【cpolar】Ubuntu本地快速搭建web小游戏网站,公网用户远程访问

简介: 【cpolar】Ubuntu本地快速搭建web小游戏网站,公网用户远程访问

前言


网:我们通常说的是互联网;站:可以理解成在互联网上的一个房子。把互联网看做一个城市,城市里面的每一个房子就是一个站点,房子里面放着你的资源,那如果有人想要访问你房子里面的东西怎么办?

在现实生活中,去别人家首先要知道别人的地址,某某区某某街道,几号,在互联网中也有地址的概念,就是ip。通过ip我们就能找到在互联网上面的站点,端口可以看做是这个房子的入口,不同的入口所看到的东西也就不一样,如从大门(80端口)进是客厅,从窗户(8080端口)进是书房。

接下来我们将通过简单几步来在ubuntu搭建一个web站点 html小游戏,并使用cpolar内网穿透将其发布到公网上,使得公网用户也可以正常访问到本地web站点的小游戏。

 

1. 本地环境服务搭建

apach2是一个服务,也可以看做一个容器,也就是上面说的房子,运行在ubuntu里,这个服务可以帮助我们把我们自己的网站页面通过相应的端口让除本机以外的其他电脑访问。

下载apach2

sudo apt install apache2 php -y



下载好后启动apache2

sudo service apache2 restart


然后打开Ubuntu 浏览器,输入:http://localhost 即可看到我们apache 默认的页面,此时说明本地站点已经搭建好了。

然后打开Ubuntu 浏览器,输入:http://localhost 即可看到我们apache 默认的页面,此时说明本地站点已经搭建好了。

进入Apache默认服务器主目录路径,这个目录放的是想要让别人看到的资源,如一张图片,一个html页面等

cd /var/www/html


进入后删掉index.html这个文件,由于apache默认页面并不是我们自己想要的页面,我们想要换成自己喜欢的页面,所以需要删掉.执行以下命令:

sudo rm -rf index.html


为了达到测试效果,我们设置一个html页面小游戏,创建名称为game.html的页面

sudo vim game.html


i键 进入编辑模式,复制以下html代码进去(复制全部)

1. <!DOCTYPE html>
2. <html>
3. <head><h4>Take it Easy!Please playing Game</h4></head>
4. <body>
5. <div></div>
6. <!-- 4个board -->
7. <div id="board1" style="position: absolute; width:80px; height:10px; left:420px; 
8.         top:555px; background-color: cadetblue;"></div>
9. <div id="board2" style="position: absolute; width:80px; height:10px; left:520px; 
10.         top:555px; background-color: cadetblue;"></div>
11. <div id="board3" style="position: absolute; width:80px; height:10px; left:620px; 
12.         top:555px; background-color: cadetblue;"></div>
13. <div id="board4" style="position: absolute; width:80px; height:10px; left:720px; 
14.         top:555px; background-color: cadetblue;"></div>
15. <!-- 小球 -->
16. <div id="ball" class="circle" style="width:20px; 
17.         height:20px; background-color:crimson; border-radius: 50%; position:absolute; 
18.         left:600px; top:100px"></div>
19. <!-- 框 -->
20. <div id="box" style="border: 5px solid #555555; width:400px; height:550px; display=hide"></div>
21. <!-- 分数 过的board越多,分数越高 -->
22. <div id="score" style="width:200px; height:10px; position:absolute; left:900px; 
23.             font-family:'隶书'; font-size: 30px;">score: 0</div>
24. <!-- 游戏结束 -->
25. <div id="gg" style="width:200px; height:10px; position:absolute; left:550px; top:200px;
26.         font-family:'隶书'; font-size: 30px; display: none;">Game Over</div>
27. <script>
28. // 设置box的样式
29.             var box = document.getElementById("box");
30.             box.style.position = "absolute";
31.             box.style.left = "400px";
32. // 设置board的样式
33.             var board1 = document.getElementById("board1");
34.             var board2 = document.getElementById("board2");
35.             var board3 = document.getElementById("board3");
36.             var board4 = document.getElementById("board4");
37. // 声音
38.             var shengyin = new Audio();
39.             shengyin.src = "声音2.mp3";
40.             shengyinFlag = 0; // 用来表示小球在第几块board上
41. // 键盘事件函数
42.             var ball = document.getElementById("ball");
43.             document.onkeydown = f;
44. function f(e){
45.                 var e = e || window.event;
46.                 switch(e.keyCode){
47.                     case 37:
48. // 按下左键,小球左移,但不要超过左边框
49. if(ball.offsetLeft>=box.offsetLeft + 10)
50.                             ball.style.left = ball.offsetLeft - 8 + "px";
51.                         break;
52.                     case 39:
53. // 按下右键,小球右移,但不要超过由边框
54. if(ball.offsetLeft<=box.offsetLeft+box.offsetWidth-ball.offsetWidth-10)
55.                             ball.style.left = ball.offsetLeft + 8 + "px";
56.                         break;
57.                     case 32:
58. 
59.                 }
60.             }
61. // 定义一个分数变量
62.             var fenshu = 0;
63. // 定义一个函数,移动给定的一个board
64. function moveBoard(board)
65.             {
66.                 var t1 = board.offsetTop;
67. if(t1<=0)
68.                 {
69. // 如果board移到最上面了,就随机换个水平位置,再移到最下面
70.                     t2 = Math.floor(Math.random() * (720- 420) + 420);
71.                     board.style.left = t2 + "px";
72.                     board.style.top = "555px";
73.                     fenshu += 1; //分数增加1
74.                     document.getElementById("score").innerHTML = "score " + fenshu;
75.                 }
76. //
77. else
78.                     board.style.top = board.offsetTop - 1 + "px";
79.             }
80. // 定义小球的速度变量
81.             var startSpeed = 1;
82.             var ballSpeed =startSpeed;
83. // step函数是游戏界面的单位变化函数
84. function step()
85.             {
86. // board直接上下隔得太近,就逐个移动,否则,同时移动
87.                 var t1 = Math.abs(board1.offsetTop - board2.offsetTop);
88.                 var t2 = Math.abs(board2.offsetTop - board3.offsetTop);
89.                 var t3 = Math.abs(board3.offsetTop - board4.offsetTop);
90. // 定义一个board之间的间隔距离
91.                 var t4 = 140;
92. if(t1<t4)
93.                 {
94.                     moveBoard(board1);
95.                 }
96. else if(t2<t4)
97.                 {
98.                     moveBoard(board1);
99.                     moveBoard(board2);
100.                 }
101. else if(t3<t4)
102.                 {
103.                     moveBoard(board1);
104.                     moveBoard(board2);
105.                     moveBoard(board3);
106.                 }
107. else
108.                 {
109.                     moveBoard(board1);
110.                     moveBoard(board2);
111.                     moveBoard(board3);
112.                     moveBoard(board4);
113.                 }
114. // 定义小球的垂直移动规则,1、向下匀加速运动,2、如果碰到board就被board持续抬上去,
115. // 直到按左右键离开了该board
116. 
117. // 如果小球的纵坐标等于某个board的纵坐标,就被抬起
118.                 var t5 = Math.abs(ball.offsetTop - board1.offsetTop);
119.                 var t6 = Math.abs(ball.offsetTop - board2.offsetTop);
120.                 var t7 = Math.abs(ball.offsetTop - board3.offsetTop);
121.                 var t8 = Math.abs(ball.offsetTop - board4.offsetTop);
122. if(t5<=ball.offsetHeight && t5>0 && ball.offsetLeft>=board1.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board1.offsetLeft+board1.offsetWidth)
123.                 {
124.                     ball.style.top = board1.offsetTop - ball.offsetHeight + "px";
125.                     ballSpeed = startSpeed;
126. if(shengyinFlag != 1)
127.                     {
128.                         shengyin.play();
129.                         shengyinFlag = 1;
130.                     }
131.                 }
132. else if(t6<=ball.offsetHeight && t6>0 && ball.offsetLeft>=board2.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board2.offsetLeft+board2.offsetWidth)
133.                 {
134.                     ball.style.top = board2.offsetTop - ball.offsetHeight + "px";
135.                     ballSpeed = startSpeed;
136. if(shengyinFlag != 2)
137.                     {
138.                         shengyin.play();
139.                         shengyinFlag = 2;
140.                     }
141.                 }
142. else if(t7<=ball.offsetHeight && t7>0 && ball.offsetLeft>=board3.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board3.offsetLeft+board3.offsetWidth)
143.                 {
144.                     ball.style.top = board3.offsetTop - ball.offsetHeight + "px";
145.                     ballSpeed = startSpeed;
146. if(shengyinFlag != 3)
147.                     {
148.                         shengyin.play();
149.                         shengyinFlag = 3;
150.                     }
151.                 }
152. else if(t8<=ball.offsetHeight && t8>0 && ball.offsetLeft>=board4.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board4.offsetLeft+board4.offsetWidth)
153.                 {
154.                     ball.style.top = board4.offsetTop - ball.offsetHeight + "px";
155.                     ballSpeed = startSpeed;
156. if(shengyinFlag != 4)
157.                     {   
158.                         shengyin.play();
159.                         shengyinFlag = 4;
160.                     }
161.                 }
162. else
163.                 {
164.                     ballSpeed = ballSpeed + 0.01; // 数字相当于加速度
165.                     ball.style.top = ball.offsetTop + ballSpeed + "px";
166.                 }
167. // ballSpeed = ballSpeed + 0.01; // 数字相当于加速度
168. // ball.style.top = ball.offsetTop + ballSpeed + "px";
169. 
170. // 如果小球跑出来box,就结束游戏
171. if(ball.offsetTop==0 || ball.offsetTop>=box.offsetTop+box.offsetHeight)
172.                 {
173.                     clearInterval(gameover);
174.                     ball.style.display = 'none';
175.                     board1.style.display = 'none';
176.                     board2.style.display = 'none';
177.                     board3.style.display = 'none';
178.                     board4.style.display = 'none';
179.                     var gg = document.getElementById("gg"); //显示游戏结束
180.                     gg.style.display = 'block';
181.                 }
182.             }
183. 
184.             var gameover = setInterval("step();", 8);
185. </script>
186. </body>
187. </html>


复制完后按Esc键退出编辑,接着输入冒号:wq保存退出即可


2. 局域网测试访问

接着浏览器输入http://localhost/game.html,即可看到html页面的小游戏站点,由于部署的是静态站点,不需要重启服务。


3. 内网穿透

由于这个站点目前只能在本地被访问到,为了使所有人都可以访问,我们需要将这个本地基础站点发布到公网。这里我们可以通过cpolar内网穿透工具来实现,它支持 http/https/tcp协议,无需公网IP ,也不用设置路由器,可以很容易将本地站点发布到公网供所有人访问。

3.1 ubuntu本地安装cpolar

如何在ubuntu上安装cpolar内网穿透,请参考这篇文章教程


3.2 创建隧道

cpolar安装成功之后,在浏览器上访问本地9200端口,登录cpolar web UI管理界面。

点击左侧仪表盘的隧道管理——创建隧道:

  • 隧道名称:可自定义,注意不要重复
  • 协议:http
  • 本地地址:80
  • 端口类型:随机域名
  • 地区:China vip

点击创建

隧道创建成功后,点击左侧的状态——在线隧道列表,可以看到刚刚创建的隧道已经有生成了相应的公网地址,将其复制下来,接下来测试访问一下。


3.3 测试公网访问

打开浏览器访问刚刚所复制的公网地址,注意,后面要加上路径/game.html,出现游戏界面即成功。

游戏控制使用:键盘上下左右键


4. 配置固定二级子域名

由于以上所创建的隧道选择的是随机域名,所生成的公网地址会在24小时内随机变化,对于需要长期访问的用户来讲较为不方便。不过我们可以为其配置一个固定的二级子域名来进行访问,改地址不会随机变化。

注意:配置固定二级子域名功能需要升级至基础版套餐或以上才支持。


4.1 保留一个二级子域名

登录cpolar官网后台,点击左侧的预留,找到保留二级子域名:

  • 地区:选择China VIP
  • 二级域名:可自定义填写
  • 描述:即备注,可自定义填写

点击保留

提示子域名保留成功,复制所保留的二级子域名


4.2 配置二级子域名

访问本地9200端口登录cpolar web UI管理界面,点击左侧仪表盘的隧道管理——隧道列表,找到所要配置的隧道,点击右侧的编辑

修改隧道信息,将保留成功的二级子域名配置到隧道中

  • 域名类型:选择二级子域名
  • Sub Domain:填写保留成功的二级子域名,本例为test01

点击更新

提示更新隧道成功,点击左侧仪表盘的状态——在线隧道列表,可以看到公网地址已经更新为保留成功的二级子域名,将其复制下来。


4.3 测试访问公网固定二级子域名

我们使用任意浏览器,输入刚刚配置成功的公网固定二级子域名+/game.html就可看到我们创建的站点小游戏了,且该地址不会再随机变化了。

目录
打赏
0
0
0
0
2
分享
相关文章
使用Web浏览器访问UE应用的最佳实践
在3D/XR应用开发中,尤其是基于UE(虚幻引擎)开发的高精度场景,传统终端因硬件局限难以流畅运行高帧率、复杂效果的三维应用。实时云渲染技术,将渲染任务转移至云端服务器,降低终端硬件要求,确保用户获得流畅体验。具备弹性扩展、优化传输协议、跨平台支持和安全性等优势,适用于多种终端和场景,特别集成像素流送技术,帮助UE开发者实现低代码上云操作,简化部署流程,保留UE引擎的强大开发能力,确保画面精美且终端轻量化。
126 17
使用Web浏览器访问UE应用的最佳实践
nginx修改网站默认根目录及发布(linux、centos、ubuntu)openEuler软件源repo站点
通过合理配置 Nginx,我们可以高效地管理和发布软件源,为用户提供稳定可靠的服务。
239 13
|
4月前
【Azure App Service】PowerShell脚本批量添加IP地址到Web App允许访问IP列表中
Web App取消公网访问后,只允许特定IP能访问Web App。需要写一下段PowerShell脚本,批量添加IP到Web App的允许访问IP列表里!
基于Ubuntu-22.04安装K8s-v1.28.2实验(四)使用域名访问网站应用
基于Ubuntu-22.04安装K8s-v1.28.2实验(四)使用域名访问网站应用
89 1
强强联手!JSF 与 Hibernate 打造高效数据访问层,让你的应用如虎添翼,性能飙升!
【8月更文挑战第31天】本文通过具体示例详细介绍了如何在 JavaServer Faces (JSF) 应用程序中集成 Hibernate,实现数据访问层的最佳实践。首先,创建一个 JSF 项目并在 Eclipse 中配置支持 JSF 的服务器版本。接着,添加 JSF 和 Hibernate 依赖,并配置数据库连接池和 Hibernate 配置文件。然后,定义实体类 `User` 和 DAO 类 `UserDAO` 处理数据库操作。
82 0
Vaadin路由魔法:导航之舟,带你穿越页面迷宫!驾驭神奇URL,解锁无限可能!
【8月更文挑战第31天】Vaadin是一款现代Java Web开发框架,其路由机制结合前后端路由,确保流畅的用户体验和高效服务器资源利用。通过`@Route`注解和`Router`类,开发者可以轻松定义和管理页面路径。例如,`@Route(&quot;home&quot;)`可指定视图路径,而参数化路由如`@Route(&quot;user/:userId&quot;)`则允许URL传参。此外,Vaadin还提供了丰富的导航API和自定义路由事件监听器,助力开发者构建结构清晰且体验优秀的Web应用。
102 0
构建高效现代Web应用:深入探讨Entity Framework Core与GraphQL在数据访问中的结合使用
【8月更文挑战第31天】随着Web应用的发展,传统的RESTful API逐渐显现出局限性,现代应用开始转向GraphQL。与此同时,Entity Framework Core(EF Core)作为强大的ORM工具,在数据访问方面表现出色,支持异步操作和自动变更跟踪,简化了数据处理。GraphQL作为一种灵活的查询语言,允许客户端精确获取所需数据,减少不必要的传输。将EF Core与GraphQL结合使用,可实现高效的数据访问和灵活的数据查询,优化数据流并提升应用性能。这种技术组合不仅提高了开发效率,还优化了用户体验,有望成为未来Web开发的重要方向。
51 0
Angular邂逅PWA:一场关于如何利用现代Web技术栈中的明星框架与渐进式理念,共同编织出具备原生应用般丝滑体验、离线访问及桌面集成能力的未来Web应用的探索之旅
【8月更文挑战第31天】本文详细介绍如何利用Angular将传统Web应用升级为渐进式Web应用(PWA),克服后者在网络依赖、设备集成及通知功能上的局限。通过具体命令行操作与代码示例,指导读者从新建Angular项目到配置`manifest.json`和服务工作进程,最终实现离线访问、主屏添加及推送通知等功能,显著提升用户体验。适合各水平开发者学习实践。
74 0
【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)
【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)
114 0
|
7月前
|
API
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误
【Azure API 管理】在 Azure API 管理中使用 OAuth 2.0 授权和 Azure AD 保护 Web API 后端,在请求中携带Token访问后报401的错误

热门文章

最新文章