【内网穿透】在Ubuntu搭建Web小游戏网站,并将其发布到公网访问

news2024/12/23 6:30:53

目录

前言

1. 本地环境服务搭建

2. 局域网测试访问

3. 内网穿透

3.1 ubuntu本地安装cpolar

3.2 创建隧道

3.3 测试公网访问

4. 配置固定二级子域名

4.1 保留一个二级子域名

4.2 配置二级子域名

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


前言

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

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

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

1. 本地环境服务搭建

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

下载apach2

sudo apt install apache2 php -y

20230215171101

下载好后启动apache2

sudo service apache2 restart

然后打开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代码进去(复制全部)

<!DOCTYPE html>
<html>
    <head><h4>Take it Easy!Please playing Game</h4></head>
    <body>
        <div></div>
        <!-- 4个board -->
        <div id="board1" style="position: absolute; width:80px; height:10px; left:420px; 
        top:555px; background-color: cadetblue;"></div>
        <div id="board2" style="position: absolute; width:80px; height:10px; left:520px; 
        top:555px; background-color: cadetblue;"></div>
        <div id="board3" style="position: absolute; width:80px; height:10px; left:620px; 
        top:555px; background-color: cadetblue;"></div>
        <div id="board4" style="position: absolute; width:80px; height:10px; left:720px; 
        top:555px; background-color: cadetblue;"></div>
        <!-- 小球 -->
        <div id="ball" class="circle" style="width:20px; 
        height:20px; background-color:crimson; border-radius: 50%; position:absolute; 
        left:600px; top:100px"></div>
        <!-- 框 -->
        <div id="box" style="border: 5px solid #555555; width:400px; height:550px; display=hide"></div>
        <!-- 分数 过的board越多,分数越高 -->
        <div id="score" style="width:200px; height:10px; position:absolute; left:900px; 
            font-family:'隶书'; font-size: 30px;">score: 0</div>
        <!-- 游戏结束 -->
        <div id="gg" style="width:200px; height:10px; position:absolute; left:550px; top:200px;
        font-family:'隶书'; font-size: 30px; display: none;">Game Over</div>
        <script>
            // 设置box的样式
            var box = document.getElementById("box");
            box.style.position = "absolute";
            box.style.left = "400px";
            // 设置board的样式
            var board1 = document.getElementById("board1");
            var board2 = document.getElementById("board2");
            var board3 = document.getElementById("board3");
            var board4 = document.getElementById("board4");
            // 声音
            var shengyin = new Audio();
            shengyin.src = "声音2.mp3";
            shengyinFlag = 0; // 用来表示小球在第几块board上
            // 键盘事件函数
            var ball = document.getElementById("ball");
            document.onkeydown = f;
            function f(e){
                var e = e || window.event;
                switch(e.keyCode){
                    case 37:
                        // 按下左键,小球左移,但不要超过左边框
                        if(ball.offsetLeft>=box.offsetLeft + 10)
                            ball.style.left = ball.offsetLeft - 8 + "px";
                        break;
                    case 39:
                        // 按下右键,小球右移,但不要超过由边框
                        if(ball.offsetLeft<=box.offsetLeft+box.offsetWidth-ball.offsetWidth-10)
                            ball.style.left = ball.offsetLeft + 8 + "px";
                        break;
                    case 32:

                }
            }
            // 定义一个分数变量
            var fenshu = 0;
            // 定义一个函数,移动给定的一个board
            function moveBoard(board)
            {
                var t1 = board.offsetTop;
                if(t1<=0)
                {
                    // 如果board移到最上面了,就随机换个水平位置,再移到最下面
                    t2 = Math.floor(Math.random() * (720- 420) + 420);
                    board.style.left = t2 + "px";
                    board.style.top = "555px";
                    fenshu += 1; //分数增加1
                    document.getElementById("score").innerHTML = "score " + fenshu;
                }
                    // 
                else
                    board.style.top = board.offsetTop - 1 + "px";
            }
            // 定义小球的速度变量
            var startSpeed = 1;
            var ballSpeed =startSpeed;
            // step函数是游戏界面的单位变化函数
            function step()
            {
                // board直接上下隔得太近,就逐个移动,否则,同时移动
                var t1 = Math.abs(board1.offsetTop - board2.offsetTop);
                var t2 = Math.abs(board2.offsetTop - board3.offsetTop);
                var t3 = Math.abs(board3.offsetTop - board4.offsetTop);
                // 定义一个board之间的间隔距离
                var t4 = 140;
                if(t1<t4)
                {
                    moveBoard(board1);
                }
                else if(t2<t4)
                {
                    moveBoard(board1);
                    moveBoard(board2);
                }
                else if(t3<t4)
                {
                    moveBoard(board1);
                    moveBoard(board2);
                    moveBoard(board3);
                }
                else
                {
                    moveBoard(board1);
                    moveBoard(board2);
                    moveBoard(board3);
                    moveBoard(board4);
                }
                // 定义小球的垂直移动规则,1、向下匀加速运动,2、如果碰到board就被board持续抬上去,
                // 直到按左右键离开了该board

                // 如果小球的纵坐标等于某个board的纵坐标,就被抬起
                var t5 = Math.abs(ball.offsetTop - board1.offsetTop);
                var t6 = Math.abs(ball.offsetTop - board2.offsetTop);
                var t7 = Math.abs(ball.offsetTop - board3.offsetTop);
                var t8 = Math.abs(ball.offsetTop - board4.offsetTop);
                if(t5<=ball.offsetHeight && t5>0 && ball.offsetLeft>=board1.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board1.offsetLeft+board1.offsetWidth)
                {
                    ball.style.top = board1.offsetTop - ball.offsetHeight + "px";
                    ballSpeed = startSpeed;
                    if(shengyinFlag != 1)
                    {
                        shengyin.play();
                        shengyinFlag = 1;
                    }
                }
                else if(t6<=ball.offsetHeight && t6>0 && ball.offsetLeft>=board2.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board2.offsetLeft+board2.offsetWidth)
                {
                    ball.style.top = board2.offsetTop - ball.offsetHeight + "px";
                    ballSpeed = startSpeed;
                    if(shengyinFlag != 2)
                    {
                        shengyin.play();
                        shengyinFlag = 2;
                    }
                }
                else if(t7<=ball.offsetHeight && t7>0 && ball.offsetLeft>=board3.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board3.offsetLeft+board3.offsetWidth)
                {
                    ball.style.top = board3.offsetTop - ball.offsetHeight + "px";
                    ballSpeed = startSpeed;
                    if(shengyinFlag != 3)
                    {
                        shengyin.play();
                        shengyinFlag = 3;
                    }
                }
                else if(t8<=ball.offsetHeight && t8>0 && ball.offsetLeft>=board4.offsetLeft-ball.offsetWidth && ball.offsetLeft<=board4.offsetLeft+board4.offsetWidth)
                {
                    ball.style.top = board4.offsetTop - ball.offsetHeight + "px";
                    ballSpeed = startSpeed;
                    if(shengyinFlag != 4)
                    {   
                        shengyin.play();
                        shengyinFlag = 4;
                    }
                }
                else
                {
                    ballSpeed = ballSpeed + 0.01; // 数字相当于加速度
                    ball.style.top = ball.offsetTop + ballSpeed + "px";
                }
                // ballSpeed = ballSpeed + 0.01; // 数字相当于加速度
                // ball.style.top = ball.offsetTop + ballSpeed + "px";

                // 如果小球跑出来box,就结束游戏
                if(ball.offsetTop==0 || ball.offsetTop>=box.offsetTop+box.offsetHeight)
                {
                    clearInterval(gameover);
                    ball.style.display = 'none';
                    board1.style.display = 'none';
                    board2.style.display = 'none';
                    board3.style.display = 'none';
                    board4.style.display = 'none';
                    var gg = document.getElementById("gg"); //显示游戏结束
                    gg.style.display = 'block';
                }
            }

            var gameover = setInterval("step();", 8);
        </script>
    </body>
</html>

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

2. 局域网测试访问

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

20230215171104

3. 内网穿透

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

3.1 ubuntu本地安装cpolar

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

  • Ubuntu用户安装Cpolar内网穿透

3.2 创建隧道

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

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

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

点击创建

20230215171105

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

20230215171106

3.3 测试公网访问

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

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

20230215171107

4. 配置固定二级子域名

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

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

4.1 保留一个二级子域名

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

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

点击保留

20230215171108

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

20230215171109

4.2 配置二级子域名

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

20230215171110

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

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

点击更新

20230215171111

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

20230215171112

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

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

20230215171113

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1039359.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

复亚智能落地江苏化工,安防巡逻无人机守牢“安全线”

化工业是国民经济的重要组成部分&#xff0c;但其生产环境和条件充满了挑战。大部分化学反应发生在高温、高压且有毒的环境中&#xff0c;而近70%的原料、中间体和终产品都带有易燃、易爆、有毒、有害以及腐蚀性的特性。在这样的情境下&#xff0c;安全生产不仅仅是一项日常任务…

leetCode 968.监控二叉树(利用状态转移+贪心)

968. 监控二叉树 - 力扣&#xff08;LeetCode&#xff09; 给定一个二叉树&#xff0c;我们在树的节点上安装摄像头。节点上的每个摄影头都可以监视其父对象、自身及其直接子对象。计算监控树的所有节点所需的最小摄像头数量。 >>解题思路: 重要线索->题目示例中的摄…

AP5126 降压恒流 PIN对PIN替LN2566 LED汽车大灯车灯驱动芯片

产品描述 AP5126 是一款 PWM 工作模式,高效率、外 围简单、内置功率管&#xff0c;适用于 12-80V 输入的高 精度降压 LED 恒流驱动芯片。输出最大功率可达 15W&#xff0c;最大电流 1.2A。 AP5126 可实现全亮/半亮功能切换&#xff0c;通过 MODE 切换&#xff1a;全亮/半…

YZ09: VBA_Excel之读心术

【分享成果&#xff0c;随喜正能量】多要求自己&#xff0c;你会更加独立&#xff0c;少要求别人&#xff0c;你会减少失望&#xff0c;宁愿花时间去修炼 不完美的自己&#xff0c;也不要浪费时间去期待完美的别人&#xff01;。 我给VBA下的定义&#xff1a;VBA是个人小型自动…

SolidJs节点级响应性

前言 随着组件化、响应式、虚拟DOM等技术思想引领着前端开发的潮流&#xff0c;相关的技术框架大行其道&#xff0c;就以目前主流的Vue、React框架来说&#xff0c;它们都基于组件化、响应式、虚拟DOM等技术思想的实现&#xff0c;但是具有不同开发使用方式以及实现原理&#…

Elasticsearch:与多个 PDF 聊天 | LangChain Python 应用教程(免费 LLMs 和嵌入)

在本博客中&#xff0c;你将学习创建一个 LangChain 应用程序&#xff0c;以使用 ChatGPT API 和 Huggingface 语言模型与多个 PDF 文件聊天。 如上所示&#xff0c;我们在最最左边摄入 PDF 文件&#xff0c;并它们连成一起&#xff0c;并分为不同的 chunks。我们可以通过使用 …

在线商城项目EShop【ListView、adapter】

要求如下&#xff1a; 1、创建在线商城项目EShop&#xff1b; 2、修改布局文件activity_main.xml&#xff0c;使用LineaLayout和ListView创建商品列表UI&#xff1b; 3、创建列表项布局list_item.xml&#xff0c;设计UI用于显示商品图标、名称和价格信息&#xff1b; 4、创…

IT监控制度,IT监控体系如何分层

IT监控系统是指监控和管理it服务管理的软件。它涵盖了监控管理、服务台管理、问题管理和变更管理&#xff0c;旨在帮助组织更有效的运营信息系统&#xff0c;提高运营事故的响应速度。  通过建立集中监控平台&#xff0c;IT监控系统与信息系统的融合可以完成统一的展示和管理…

ICMP差错包

ICMP报文分类 Type Code 描述 查询/差错 0-Echo响应 0 Echo响应报文 查询 3-目的不可达 0 目标网络不可达报文 差错 1 目标主机不可达报文 差错 2 目标协议不可达报文 差错 3 目标端口不可达报文 差错 4 要求分段并设置DF flag标志报文 差错 5 源路由…

【从0学习Solidity】 50. 多签钱包

【从0学习Solidity】50. 多签钱包 博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&#xff0c;探索全栈…

Mac磁盘空间满了怎么办?Mac如何清理磁盘空间

你是不是发现你的Mac电脑存储越来越满&#xff0c;甚至操作系统本身就占了100多G的空间&#xff1f;这不仅影响了电脑的性能&#xff0c;而且也让你无法存储更多的重要文件和软件。别担心&#xff0c;今天这篇文章将告诉你如何清除多余的文件&#xff0c;让你的Mac重获新生。 一…

【kafka实战】01 3分钟在Linux上安装kafka

本节采用docker安装Kafka。采用的是bitnami的镜像。Bitnami是一个提供各种流行应用的Docker镜像和软件包的公司。采用docker的方式3分钟就可以把我们想安装的程序运行起来&#xff0c;不得不说真的很方便啊&#xff0c;好了&#xff0c;开搞。使用前提&#xff1a;Linux虚拟机&…

找不到msvcp110dll,无法继续执行代码,msvcp110dll丢失是什么意思

MSVCP110.dll是一个动态链接库文件&#xff0c;它是Microsoft Visual C 2012 Redistributable package的一部分。这个文件通常用于支持许多Microsoft Visual Studio 2012开发的应用程序。当您在运行某些程序时遇到“找不到msvcp110.dll”的错误时&#xff0c;这意味着您的计算机…

PHY6230低成本遥控灯控芯片国产蓝牙BLE5.2 2.4G SoC

高性价比的低功耗高性能蓝牙5.2系统级芯片&#xff0c;适用多种PC/手机外设连接场景。 高性能多模射频收发机&#xff1a; 通过硬件模块的充分复用实现高性能多模数字收发机。发射机&#xff0c;最大发射功率10dBm&#xff1b;BLE 1Mbps速率接收机灵敏度达到-96dBm&#xff1…

查准率(precision,也叫精确率)和查全率(recall,也叫召回率)

精确率和召回率是广泛用于信息检索和统计学分类领域的两个度量值&#xff0c;用来评价结果的质量。其中精确率是检索出相关文档数与检索出的文档总数的比率&#xff0c;衡量的是检索系统的查准率&#xff1b;召回率是指检索出的相关文档数和文档库中所有的相关文档数的比率&…

【算法小课堂】滑动窗口

滑动窗口 基本概念&#xff1a; 滑动窗口本质是双指针算法的一种演变 本质上就是同向双指针&#xff0c;窗口的范围就是[left,right&#xff09; 滑动窗口大致可以分为两类 窗口大小不变的窗口大小变化的 滑动窗口遇到一些验证重复性的问题的时候可以用哈希表来优化 核心思想…

​旅行季《乡村振兴战略下传统村落文化旅游设计》许少辉八一书作想象和世界一样宽广

​旅行季《乡村振兴战略下传统村落文化旅游设计》许少辉八一书作想象和世界一样宽广

DAZ To UMA⭐二.设置DAZ导出的形态键 和 Daz贴图位置

文章目录 🟧 形态键介绍及在Unity3D中的用途1️⃣ Daz中的形态键2️⃣ Blender 中的形态键3️⃣ 形态键在Unity中的作用🟩 设置DAZ导出的形态键1️⃣ 找到要导出的形态键名称2️⃣ 打开导出面板3️⃣ 设置导出规则举例 : 导出身体Morphs举例:导出嘴部Morphs🟦 获取模型纹…

uni-app 之 去掉顶部导航

uni-app 之 去掉顶部导航 uniapp怎么样去掉顶部导航 uniapp去掉顶部导航的方法&#xff1a; 1、去掉所有导航栏&#xff1b; 2、单一页面去掉顶部导航栏。 image.png uniapp去掉顶部导航的方法&#xff1a; 1、去掉所有导航栏 "globalStyle": {"navigationBar…

个人电脑怎么搭建服务器 花生壳内网穿透 设置路由器虚拟服务器

在个人电脑上搭建服务器并使用花生壳进行内网穿透&#xff0c;以及在路由器上设置虚拟服务器&#xff0c;需要一些步骤&#xff1a; 内网穿透设置&#xff1a; 配置内网穿透&#xff0c;选择服务器软件的端口号&#xff0c;然后将其映射到您的服务器的内部IP地址和端口号。这将…