这篇文章主要是为了记录自己学习首次做直播网站的基础,我从官方网站看找到一个小demo,毕竟东西都需要有一个小入门,不可以无论三七二十动手,那样做完的东西,自己都不理解是什么。
学习是一个过程,即使有人给你一样的教程,自己也必须动手实现一遍才能明白其中的道理以及解决实际碰到的问题。问题以及解决思路都是自己的,积累是一个过程。此文章是一个持续add内容的过程。未完待续...
一、将项目提交到自己github内
说起来可笑,博主跟着公司项目,只知道如何从某仓库clone项目下来进行实际的代码操作。但是自己并没有去创建过仓库,更没有将本地项目提交到仓库内。所以第一步开始我好像就比别人落后很多嘻嘻。
首先我是在本地创建了springboot的项目。所以首先要将代码与远程仓库进行挂载,由此引出以下步骤。
1.为本地项目成为git可管理项目
这一步很简单,当我们安装过git后,进入自己的项目文件夹内。输入以下命令,使其可以成为git可管理项目,执行后会产生.git文件,是一个隐藏型文件。
$ git init
2.将项目内容存到自己的本地工作区
这一步主要是将项目所有内容添加到git的本地仓库工作区内。输入以下命令,注意结尾有一个" . "。
$ git add .
3.将工作区代码存入暂存区。
这一步是将我们提交在工作区内的代码提交到本地git仓库的暂存区内。输入以下命令。
$ git commit -m " init project"
4.创建github仓库
这一步很简单,我们登陆自己的github,找到repostitories,点击new,按照自己所需进行内容填写,就完成了。很简单。
5.为repository挂载项目
当我们创建好仓库以后,会出现一个页面,页面中会展示一个https链接,图片中的链接就是我们进行挂载的关键。
输入以下命令,将本地的项目挂载到远程仓库内。后面的https链接填写自己的git链接。
$ git remote add origin https://github.com/***
6.将代码提交到远程仓库
上一步只是挂载了关联,实际代码还未提交。通过以下命令,我们可以将刚刚放在暂存区的代码push到远程仓库内。其中-u是因为这是我们第一次提交时输入的参数。此后就不需要加-u就可直接提交自己的代码变动到远程仓库了。
$ git push -u origin master
7.查看
此时我们可以查看自己的github项目了,刷新后可以发现项目已经提交上来了。
二、setting文件配置
说起这个也是尴尬,本人的maven配置文件是公司的,而公司是自己的私服,会导致很多jar包使用的局限性,故而我决定重新配置一下setting文件。因为对mac本还是有点不熟悉,所以找setting文件还浪费了一小小会。我们的setting文件一般都是放在了自己用户空间下,是隐藏文件。其实很好找。
本来我研究了一会settng文件内的各项配置及作用,最终发现,对于我这样的个人项目来说,只需要一个一项就够,所以我将其中所有配置删除,只留下了一部分。其中下载源我修改为阿里云,这样比较快。
三、实际开发过程
今天才开始动手开发,开发的demo很简单,但是过程中碰到的一系列问题可是耽误了不少时间。为此我也暗暗的跟自己说,万事开头难,万事开头难....到以后就没问题了。
首先项目我打算基于springboot框架进行开发,只是过程中会涉及到一些前端的东西,我不得不说。作为一个后端开发人员,这些我只在久远的时候用springMvc模式下开发过,根本没利用springboot去开发过,所以我的开始也是一头雾水。中间现学了那么一点点的网页知识。好了,废话不多说,开始我的崎岖路。
1.创建一个springboot项目。
我这里为了方便,直接进入官网,输入自己项目的基本信息后,download下来一个,利用idea直接open了出来,很简单,下面贴出地址。
URL:https://start.spring.io
2.贴出pom文件配置
这里是为了我们后续的开发能够顺利进行,这里也有一点小插曲。当我将配置完成后,自然的利用idea的便捷,从旁边工具栏点击了install,想让其自动下载我这些包文件。不过我也没检查仔细,就这么过去了,到后来我发现网页怎么都调不通,再细瞅,看到右下角有一个import的提示,我就点了一下,再进行查看,果不其然,项目可以调通了。这也是本人的疏忽,下次我一定乖乖用命令的mvn -install来执行。
2.创建实体类
既然是客户端与服务端的通讯,那么我们就至少需要建立2个实体类。
客户端消息类:
其中我们只接受用户的姓名值,这里用到了lombok的插件,可以方便我们生成get以及set方法,额外两个是无参构造函数及有参构造函数的注解。
服务端消息类:
3.webSocket配置类
这里也出了一个小问题,就是我在启动项目后,点击了connection按钮,竟然没有任何反应,也找不到对应的配置,着实纳闷了挺久。我试了debug模式,但是项目是在访问html文件时报错的,也就是在html文件内的js文件中,会创建及连接到对应的配置类,但此时配置类不生效了。所以我觉得问题可能就是出在了配置类,进而怀疑是否此类根本没有注入到spring管理容器内,所以我排查了一下,起初我添加了一个componet的注解,项目竟然可以正常访问了。我懵逼了,觉得应该没问题的啊,后来我发现,呵呵,我犯了一个蠢事,我把Configuration注解错写成了Configurable。呵。
这个配置类,可以通过代理去实现客户端的连接功能。其中配置的意义为写在注解内了,如果有不正确的地方,还望指出。
4.Controller类
既然是通讯demo,怎么可能没有前端控制类去接受请求呢,在此创建了一个控制类。
注意这里注解必须使用@controller,不可以使用@restController,因为我们这里涉及到了动态页面,需要返回对应的视图model,而@restController只可以返回实体。
这里的@MessageMapping配置了控制类的访问地址,我这里叫做hello。
@SendTo在我的理解内是,将此方法的消息内容广播到对应/topic/greetings的客户端内,也就是说,客户端订阅地址为/topic/greetings时,就会收到这个消息的返回内容值。
这里我们还可以注意到一个方法,就是getHtml方法,此方法专门用于我们初始化访问的,因为我们的项目无法直接去调用controller,我们需要先展示前端页面,进而通过用户操作去访问后端。
这个方法就是用来调取展示前端页面的,其中我们可以通过访问http://127.0.0.1:8080/getHtml去得到对应的webIndex页面,此处是动态代理生成,故而省去html后缀。为了能够成功访问此页面,我们还需对application.properties进行配置。注意必须有对应的thymeleaf的pom文件配置。
5.前端html文件
为了大家方便,为直接贴了代码,只是简书不太好啊,没有类似markdown这样的格式控制。看起来还是挺乱的。大家将就下哦。
其中主要的逻辑文件在与app.js文件内,而此文件只是页面的展示,比较简单。
<!DOCTYPE html>
<html>
<head>
<title>Hello WebSocket</title>
<link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="/webjars/jquery/3.1.0/jquery.js"></script>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>
<script src="app.js"></script>
</head>
<body>
<noscript><h2 style="color: #ff0000">Seems your browser doesn't support Javascript! Websocket relies on Javascript being
enabled. Please enable
Javascript and reload this page!</h2></noscript>
<div id="main-content" class="container">
<div class="row">
<div class="col-md-6">
<form class="form-inline">
<div class="form-group">
<label for="connect">WebSocket connection:</label>
<button id="connect" class="btn btn-default" type="submit">Connect</button>
<button id="disconnect" class="btn btn-default" type="submit" disabled="disabled">Disconnect
</button>
</div>
</form>
</div>
<div class="col-md-6">
<form class="form-inline">
<div class="form-group">
<label for="name">What is your name?</label>
<input type="text" id="name" class="form-control" placeholder="Your name here...">
</div>
<button id="send" class="btn btn-default" type="submit">Send</button>
</form>
</div>
</div>
<div class="row">
<div class="col-md-12">
<table id="conversation" class="table table-striped">
<thead>
<tr>
<th>Greetings</th>
</tr>
</thead>
<tbody id="greetings">
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>
6.app.js文件
前端中主要控制逻辑的文件就是app.js,我们也是通过这里与后端建立实际的连接。
这里我们重点关注的是sockjs这个对象。通过这个对象,我们建立与服务端的连接,这个socket对象在初始化时便设置了访问的地址,其地址配置的就是我们当初在后端的webSocketConfig内所配置的url。
针对这个对象配置其订阅频道,也就是我们当初controller内配置的sendTo地址。所以其终极奥义就是!访问到webSocketConfig,初始化对应的webSocket配置,而后通过点击页面上的connection按钮后可以访问到sendName函数进而直接调用到对应的Controller,Controller广播响应结果。
var stompClient = null;
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) {
$("#conversation").show();
}
else {
$("#conversation").hide();
}
$("#greetings").html("");
}
function connect() {
var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (greeting) {
showGreeting(JSON.parse(greeting.body).content);
});
});
}
function disconnect() {
if (stompClient !== null) {
stompClient.disconnect();
}
setConnected(false);
console.log("Disconnected");
}
function sendName() {
stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}
function showGreeting(message) {
$("#greetings").append("<tr><td>" + message + "</td></tr>");
}
$(function () {
$("form").on('submit', function (e) {
e.preventDefault();
});
$( "#connect" ).click(function() { connect(); });
$( "#disconnect" ).click(function() { disconnect(); });
$( "#send" ).click(function() { sendName(); });
});
至此一个简单的前后端连接与通讯就完成了。我们可以看下效果图。
其中点击connect可以连接服务器,disconnect断开连接,输入自己的name进行发送,服务端响应广播结果。