网络课程websocketreact.js前端_第1页
网络课程websocketreact.js前端_第2页
网络课程websocketreact.js前端_第3页
网络课程websocketreact.js前端_第4页
网络课程websocketreact.js前端_第5页
已阅读5页,还剩33页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

摘要知识贮藏在谦虚的大海中。在物质越来越充实的年代,知识方面的匮乏反而越来越突出。因此,网上慕课或是网上书籍应运而生。在国外,“微课程”概念最早是由美国戴维首创的。而在微课的持续发展过程中,国外对于微课程的研究拓展于不同的各个方面。在国内,由于流媒体的发展,微课程成为了一个里程碑级的产物。在这个产品中,用户可以在网上选择自己感兴趣或是想要了解的课程,随时随地听课学习。软件分为两个主页面,商城页面以及用户信息页面。商城页面为专栏、课程的列表,具备搜索功能;用户信息页面为用户个人信息的展示。在搭建工程之前,首先要捋清楚该产品的整体框架、各个模块之间的关系以及绘制出所需的后台数据库、整理各个变量之间的关系等。本书首先介绍了H5网络课程的发展前景以及现状,其次分析了开发该平台所需要用到的技术,如react.js、websocket、typescript等,其中react.js为本次开发的主技术栈。接着是各个页面、模块的单独介绍,首先是样式(截图展示),而后将页面内较为重要的模块单独拎出来讲解实现的主要技术以及步骤。为了方面展示,在本产品中特意将录像源以及展示源安置在同一个页面内以便观察现象。直播实现所需要的技术websocket是本书的一个重点,它需要客户端以及服务器端两边的配合,websocket可以认为是http协议的升级版本,两者没有必要的联系。最后即是在前端页面开发过程中所遇到的、容易遇到的问题,如页面兼容性、页面性能等,本书也进行了详细的总结。关键词:网络课程,websocket,react.js,前端

AbstractKnowledgeisstoredintheseaofmodesty.Intheeraofmaterialenrichment,thelackofknowledgehasbecomemoreandmoreprominent.Consequently,onlinecourseworkoronlinebooksbebornattherightmoment.Inforeigncountries,theconceptof"micro-curriculum"wasfirstinventedbyDavidoftheUnitedStates.Inthecourseofthesustaineddevelopmentofmicro-coursesforeignresearchonmicro-curriculumhasexpandedtodifferentaspects.InChina,duetothedevelopmentofstreamingmedia,micro-curriculumhasbecomealandmarkproduct.Inthisproduct,userscanchoosecoursestheyareinterestedinorwanttoknowonline,andlistentothemanytimeandanywhere.Thesoftwareisdividedintotwomainpages,mallpagesanduserinformationpages.Themallpageisalistofcolumnsandcourseswithsearchfunction,andtheuserinformationpageisadisplayoftheuser'spersonalinformation.Beforebuildingtheproject,firstofall,weneedtounderstandtheoverallframeworkoftheproduct,therelationshipbetweenthevariousmodules,anddrawtherequiredbackgrounddatabase,sortingouttherelationshipbetweenthevariousvariables,andsoon.ThisbookfirstintroducesthedevelopmentprospectsandcurrentsituationofH5networkcourse.Secondly,itanalysesthetechnologiesneededtodeveloptheplatform,suchasreact.js,websocket,typescriptandsoon.Amongthem,react.JSisthemaintechnologystackforthisdevelopment.Nextistheindividualintroductionofeachpageandmodule,firstisthestyle(screenshotdisplay),andthenthemoreimportantmoduleinthepageiscarriedoutseparatelytoexplainthemaintechnologyandstepsofimplementation.Foraspectdisplay,thevideosourceandthedisplaysourcearespeciallyplacedinthesamepageinordertoobservethephenomenon.Websocketisoneofthekeytechnologiesinthisbook.Itneedsthecooperationofbothclientandserver.websocketcanberegardedasanupgradedversionofHTTPprotocol.Thereisnonecessaryconnectionbetweenthetwo.Finally,thisbookalsogivesadetailedsummaryoftheproblemsencounteredinthefront-endpagedevelopmentprocess,suchaspagecompatibility,pageperformanceandsoon.Keywords:webcourse,websocket,react.js,front-end

目录TOC\o"1-3"\h\u1绪论 绪论1.1网络微课平台的意义对于爱好学习、想要时时对知识充充电的人来说,只有课下一个学习形式是很不够的,不仅路途遥远而且时间上有的可能也安排不过来。所以在网络异常发达的今天,我们应该充分利用网络的优势,让学习、读书变得更加容易。近年来,网上慕课的兴起相信很多学校的学生以及老师都有所了解,由此基础上,很多企业都争相效仿开发出一系列微课app,如乐儿思、千聊、荔枝微课等等。在这些平台上,人们可以根据自己的意愿选择想要听什么课、不想要听什么课。不仅如此,这些软件还有一个特点就是“三人行,人人皆可为师”。只要你有可以跟众多网友分享的经验或是知识,都可以自己单独开一门课程上传到平台上,如果平台判定你的课程是有价值的、值得传播的还会帮你包装、推广出去。由此可看出,微课这一类app是近几年的大热,而在这个“求贤若渴”的时代,抓住群众的心理,通过一些渠道或是活动营销方法把一些有价值的课程推销出去是一个很好的商机。1.2微课平台的现状《国家中长期教育改革和发展规划纲要(2010-2020年)》和《教育信息化十年发展规划(2011-2020年)》两个文件都明确指出:要将教育信息化纳入国家信息化发展整体战略,要充分发挥现代信息技术优势,注重信息技术和教育的全面深度融合。这为微课提供了政策支持。以下为目前几个微课平台的简略介绍:(1)荔枝微课:荔枝微课是一个大众皆可用的知识、生活常识等互相交流的平台。在荔枝微课里,每个人都可以创建课程并分享你所想要告诉听众的知识,同样也可以点开课程入口听课学习。平台支持零门槛开课,支持微信公众号、APP和电脑多种方式听课开课,拥有语音、图片、PPT、视频、音频等多种讲课模式。该平台开课丰富多样,包含自我成长、情感关系、职场提升、投资理财、育儿教育等各个方面[2]。(2)千聊:千聊由腾讯众创空间孵化,是国内领先的在线知识社区,是一个专注于知识分享的平台,通过直播的形式让您直接找到各个领域的专家、老师、达人[3]。在该平台上,用户们可以进行在线互动、交流,互相讨论学术或是观点。当然,也可以对自己感兴趣的课程进行购买,随时回听回看、重温课程,巩固知识。1.3微课平台应用前景展望在网络不断发展的这个时代,微课平台将与虎牙直播、微博、facebook等这一类平台一样,具有十分广阔的应用前景。对于教师来说,这是一个很大的教学方式上的改革,突破了一直以来传统的、受限的听课、授课形式,可以随时随地听课、授课,使得课程更加具备针对性以及时效性,是传统课堂的一个资源拓展和重要补充。虽说网络授课形式无法取代传统授课形式,但是这两种授课形式在当今时代是相辅相成的,目前也已有许多学校以及教师运用网络课程来辅助教学。网络课程不仅可以补充课堂上的各种知识,也可以补充课外的知识,让学生不再是只会单纯的学习语数英的“书呆子”,而是在生活上也能够学会做个“聪明人”。相信在不久后,网络授课的形式将会越来越受欢迎,应用也将会越广泛。1.4本章小结本章主要对微课平台类软件的意义进行了一番详细讨论,对微课平台的发展现状以及应用前景做了基本的介绍。下一章将对如何构建微课平台的大致架构设计思路以及模块做详细的解说。

2设计思路和相关技术介绍2.1设计思路以及模块在该网络微课平台中,主要将其分为两个部分:课程展示页面(tab:商城)以及用户信息页面(tab:我的)。“商城”页面里面主要内容就是课程的列表展示,拓展一个搜索课程功能;“我的”页面里面主要是包含用户信息、管理列表,外加用于营销的收益展示。如下图所示:商城商城搜索功能列表展示用户信息我的收益展示管理列表图2.1本设计的各模块分布代码结构设计如下:appappmodelImagesContextConfigContainersComponentStylesUtil图2.2代码结构图各模块释义:Component:复用组件代码;Containers:各页面代码;Config:配置文件代码;Context:上下文代码;Images:本地图片文件夹;Model:接口模板代码;Util:各接口代码;Styles:各样式表代码2.2相关技术介绍在本次设计中,主要使用的开发工具是vscode,辅助工具是photoshop、git、chrome浏览器;主要使用的脚本语言/框架为Html5、Css3、React.js、Typescript。下面主要介绍一下编程工具Vscode、作图工具Photoshop、React.js以及Typescript。VscodeVscode全名叫VisualStudioCode,是由美国微软公司开发的一个运行于MacOSX、Windows和Linux之上的,针对于编写现代Web和云应用的跨平台源代码编辑器[4]。该编辑器聚合了任何一款现代编辑器所应该具备的特性,包括语法高亮,热键绑定,括号匹配以及代码片段收集,同时也具备对Git的开箱即用的支持。该编辑器也能够使用webstorm、sublime等软件替代,这些编程软件都是经过本人实践过认为较好用的软件。PhotoshopPhotoshop是由Adobe公司开发的一款图片编辑软件,也是为今较多人用且较好用的一款软件。从功能上看,它具备图像编辑、图像合成、特效制作等,还可以缩小、放大、去除图像的斑点等操作,在图片制作、广告摄影、网页设计上面都有它的身影。Photoshop软件可以把几张很普通的图片和设计者的思路、想法联系在一起,操作简便易懂,使设计、创作者能将更多的时间放在构思画面上去。(3)React.jsMVC框架是模型(model)-视图(view)-控制器(controller)的缩写。MVC分层这种层次分明的结构对管理一些较为复杂的应用程序有很好的帮助,它具有耦合性低、重用性高、生命周期成本低、可维护性高等优点。React.js是由Facebook公司研发的一个用于构建组件化UI的库,由于它的性能出众、代码逻辑简单,渐渐的越来越受程序员们的关注与喜爱。它介绍了JavascriptXML和JSX的使用,是Javascript的语法拓展。在使用React框架时,可以充分利用React的官网,里面有详细的使用教程供开发者们查阅学习。(4)TypescriptTypescript是由微软开发的开源的编程语言,它是Javascript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。2.3数据库图表设计在开发中,难免会遇到有前端与后台之间数据的交互,这个时候,就需要后台的数据库的支持。下面是在该需求中所需要的两个主要的数据库,在用户信息页面中,主要是用户各个信息的图表:图2.3用户信息表接下来是商城页面中所需要的课程各方面信息的图表:图2.4课程信息表当前端页面需要用到这些信息或者更新这些信息的时候,就会用axios去访问后台接口,返回的res.data.data就是前端所需要的数据列表。2.4论文结构本文主要将所需要阐述的内容分为七章来展示,分别为以下:(1)绪论:主要对微课平台类软件的意义进行了一番详细讨论,对微课平台的发展现状以及应用前景做了基本的介绍;(2)设计思路和相关技术介绍:主要介绍了该网络微课平台的设计思路以及所需要用到的各个相关软件,如:vscode、photoshop等,着重介绍了这两款软件的功能、用途以及两项主要的编程技术点:React.js、Typescript,并且将两个主要的数据库设计以及论文结构设计在文中加以说明;(3)React组件化:主要讲述了react的生命周期函数以及react最重要的部分——组件之间的通信方式;(4)课程展示:主要介绍了商城展示页面、点击相应课程所进入的专栏页面和搜索功能的页面样式以及相应代码。在本章所介绍的各个页面中,主要是前端排版、样式的工作量以及搜索功能方面的逻辑代码的实现;(5)直播实现:主要介绍了websocket协议以及如何利用该协议分别在客户端、服务端实现直播功能;(6)用户信息页面:主要展示了用户信息页面的各个模块,大部分都是页面样式方面的工作;(7)问题总结:主要介绍了一些在前端开发方面需要注意的兼容性以及性能的影响,并且记录了几个在开发过程中所遇见的bug。2.5本章小结本章主要介绍了该网络微课平台的设计思路以及所需要用到的各个相关软件,如:vscode、photoshop等,着重介绍了这两款软件的功能、用途以及两项主要的编程技术点:React.js、Typescript,并且将两个主要的数据库设计以及论文结构设计在文中加以说明。

3React组件化将一个完整模块的代码拆分为组件之后,不可避免的就会遇到一些组件与组件之间需要数据传递的问题,这就是组件之间的通信。组件之间的通信又分为兄弟组件通信(同个父组件)、子组件向父组件通信、父组件向子组件通信等。兄弟组件之间的通信其实就是子组件向父组件传值、父组件向子组件传值这两个过程的结合。接下来将一一介绍。3.1生命周期函数在介绍各个组件之间传值的过程之前,先来介绍以下react的生命周期函数。React生命周期分为三种状态:初始页面结构组建以及渲染(mount)、更新(update)、卸载(unmount)。初始化时常用的由render()、componentWillMount()、componentDidMount(),更新时常用的有componentWillReceiveProps(nextProps)、componentDidUpdate(),销毁时常用的有componentWillUnmount()。render()render即为组建渲染,主要步骤是创建虚拟dom、进行diff算法、更新dom树。react这类框架的特点是能够实现数据改变视图,即代码中利用state状态机更新数据后,react会自动启用diff算法,当计算结果与state更新前不一样时,自动更新dom树。componentWillMount()该函数只在组件初始化时调用一次,此后都不再调用,此时可以修改ponentDidMount()该函数在组件渲染之后调用。componentWillReceiveProps(nextProps)该函数在组件初始化时不调用,但是在组件更新时,接收到新的props时调用。componentDidUpdate()该函数在组件初始化时不调用,但是在接下来的组件每次更新完毕之后调用,此时可以获取dom节点。componentWillUnmount()该函数在组件将要卸载时调用,在这之前如果前面有设置一些事件监听或者定时器的话,需要将之清除。3.2父组件向子组件传值不同于vue.js,react.js的数据流动是单向的,父子组件之间的通信是通过props传递所需要的信息。在父组件中,假如要调用子组件,并将状态传递给子组件,可以这样写:<ChildifShow={this.state.ifShow}/>如此,在子组件时想要获取父组件中的ifShow可以这样写:{ps.ifShow&&<div>是否显示</div>}利用与运算符或者三元运算符能够灵活地控制在react中组件或者部分模块的渲染与否。此时,如果父组件中ifShow为true,在子组件中就会渲染出“是否显示”几个字,相反的,若父组件中ifShow为false,在子组件中就不会显示。3.3子组件向父组件传值若是子组件要向父组件传递数据,则主要是通过回调函数来实现。在子组件中:<div>我是子组件<buttononClick={ps.hideComponent}>隐藏子组件</button></div>在父组件中:<div><buttononClick={this.showComponent}>显示子组件</button>{this.state.isShow?<ChildhideComponent={this.hideComponent}/>:null }</div>其中,showComponent与hideComponent函数定义如下:showComponent=()=>{this.setState({isShow:true,});}hideConponent=()=>{this.setState({isShow:false,});}此时,点击子组件内的button就能通过回调函数使父组件内的isShow值改变,从而控制子组件的渲染与否。3.4子组件与子组件之间的通信子组件与子组件之间的通信又分为跨级组件通信(不同父组件)及兄弟组件通信(同一个父组件)。兄弟之间传递数据是通过相同的父级组件作为“媒介”来实现,而跨级组件之间的数据传递普遍是使用context。Context即上下文,属于react的高级API。它是一个当开发者不想一级一级地传递props以及state来传递数据时,可以提供跨层级组件数据传递功能的对象。3.5本章小结本章主要讲述了react的生命周期函数以及react最重要的部分——组件之间的通信方式。

4课程展示4.1商城页面在商城页面中,主要包含搜索栏、海报部分、推荐课程部分、浮窗部分,点击即可进入相应的课程或是活动页面进行听课、购买等操作。由于主页的推荐课程经常变动,所以相应的文本或是图片均为后台配置,可减少后期页面改动时前端的工作量。样式如下图所示:图4.1商城页面样式4.2搜索功能在众多的课程里面,如何让用户能够快速定位到自己感兴趣的课程呢?在这个时候,搜索功能是必不可少的。搜索的实现主要思路就是在课程数据库中利用相似查找、关键字查找等方法,将名字符合搜索条件的课程陈列下来,供用户选择。如此一来,能够减少很多用户查找的时间以及精力,使得用户体验感更佳。搜索页面的样式如下:图4.2搜索页面众所周知,百度搜索引擎是通过GET请求实现搜索功能的,最浅显的表现就在于在页面url上“佩戴”搜索参数。搜索框中根据用户输入的关键字,发起请求时请求路径为当前页面路径‘/search’。该搜索功能主要利用springmvc框架以及mybatis实现,可以对指定的关键字进行搜索。MyBatis支持普通SQL查询,存储过程和高级映射。控制层代码如下:@GetMapping("/search")publicStringlist(@RequestParam(required=false,defaultValue="1",name="p")IntegerpageNo,@RequestParam(required=false,defaultValue="")StringproductName,Modelmodel){Map<String,Object>searchParam=newHashMap<>();searchParam.put("productName",productName);PageInfo<Lizhi>pageInfo=lizhiService.findByPageNo(pageNo,searchParam);model.addAttribute("pageInfo",pageInfo);return"search/list";}当搜索结果过多时,为了摒弃旧时“上一页”、“下一页”的分页模式,我们采用监听页面滚动的方法来进行懒加载,在react中使用触发事件实现如部分代码如下:<SearchBoxsearchReq={this.handleSearch}link={false}/>handleSearch(value:string){if(value){this.setState({liveList:[],searchStr:value,page:1,initialized:false},()=>this.getList());}}getList(){if(this.state.init){this.setState({init:false});}const{page,searchStr}=this.state;sessionStorage.setItem('searchValue',searchStr);axios.get('/search/channel',{params:{q:searchStr,page:page,per_page:20}}).then((res)=>{letlist=res.data.data;lethasMore=list.length>0;list=this.state.liveList.concat(list);this.setState({hasMore:hasMore,liveList:list,total:res.data.pages,initialized:true,page:page+1});});}4.3专栏页面一系列课程构成一个专栏,在商城中点击某个具体课程专栏即可进入专栏页面。页面内主要包含海报部分、课程介绍部分以及课程目录部分,如下图所示:图4.3专栏页面在专栏页面中,重点部分是底部的“试听”功能。试听时运用的是html5新增的audio标签,主要技术难点在于播放进度条的样式以及拖动控制播放进度功能的实现。由于主要是手机端展示的页面,所以拖动事件的监听主要是依赖手机端的触摸事件,由ontouchstart、ontouchmove、ontouchend一类,而拖动进度条的具体长度依赖于clientX、offsetX等。点击“试听”按钮之后,试听列表以及播放进度条样式如下图所示:图4.4试听列表界面试听部分代码展示见附录。4.4本章小结本章中,主要介绍了商城展示页面、点击相应课程所进入的专栏页面和搜索功能的页面样式以及相应代码。在本章所介绍的各个页面中,主要是前端排版、样式的工作量以及搜索功能方面的逻辑代码的实现。在下一章中,将介绍最主要的直播功能实现所需要的技术。

5直播实现5.1websocket技术目前为止,轮询是实现实时通信的最常用的方法,而实时推送,毋庸置疑也会用到轮询。轮询是在固定的时间间隔内,客户端向服务器请求数据,然后由服务器将数据返回给客户端展示。一开始主流的是使用AJAX轮询的方式来进行通信,但是这种轮询方式有一定的延时,还会对服务器造成一定的负载。直到2011年,websocket才被标准化。直播即推送,H5页面中能够实现直播的技术有很多,目前web上比较主流的方案是使用HLS和RTMP,在这里介绍的是一个较为简便的利用websocket协议实现直播的方法。WebSocket是一种在单个TCP连接上进行全双工通信的协议[5],它使得服务器与客户端之间的通信从繁琐的三次握手、四次握手演变成一次长连接即可保持通信的状态,允许服务器主动向客户端推送数据。图5.1建立握手时序图但是websocket有一个限制即在不支持websocket的设备上是无法使用的。Websocket在服务器端的实现非常丰富,可以使用node.js、c++、java、python等多种解决方案。5.2socket.io由于websocket原生的API用起来可能没有那么方便,所以就有了socket.io.js这款集成的插件,它所提供的API能供开发更方便得使用。Socket.io将websocket和AJAX轮询进行封装,实际是websocket的父集,实现了跨浏览器的双向数据传输。它典型的应用场所有:实时聊天应用、文档合并、二进制流传输等等。客户端和服务端的socket是一个关联的EventEmitter对象,客户端socket发出的事件可以被服务端的socket接收,同理,服务端socket发出的事件也可以被客户端接收。基于该机制,可以实现双向交流。socket.io由两部分组成,与Node.JSHTTPServer集成(或安装)的服务器以及客户端库。在开发过程中,想要使用socket.io插件首先要安装该模块:npminstall--savesocket.io除了简单的客户端与服务器相互传递消息之外,socket.io还提供广播功能,由于本例中没有应用到,故在此不详细叙述。5.3websocket客户端实现Websocket在客户端的编程只需要使用现成的websocketAPI即可,首先创建一个websocket对象:varSocket=newWebSocket(url,[protocol]);Websocket事件(1)open:连接建立时触发,监听事件使用onopen属性;(2)message:当客户端接收服务端数据时引发该事件,监听事件使用onmessage属性;(3)error:当通信过程中出现错误时引发该事件,监听事件使用onerror属性;(4)close:当websocket连接关闭时引发该事件,监听事件使用onclose属性。Socket.io实现(1)建立一个socket连接varsocket=io(“ws://localhost:3001”);(2)socket.on:监听服务器消息,监听的事件主要有message(消息传输)、connect(连接成功)、disconnect(断开连接)、error(发生错误)等。(3)socket.emit:向服务器发送数据,格式为socket.emit(‘msg’,{data:‘string’});图5.2socket.emit事件连接过程中,触发的事件为:connecting->connect;失去连接过程中,触发的事件为sh:disconnect->reconnecting->connecting->reconnect->connect。代码展示Html代码:<divclassName={style.start}onClick={this.begin.bind(this)}>开始录制</div>Typescript代码:begin(){varwsURL=`ws://${document.domain}:3001`;varsocket=io(wsURL);console.log(socket)varback=this.output.current;//返回一个用于在画布上绘图的环境。if(back){varbackcontext=back.getContext('2d');}varvideo=this.source.current;varsuccess=function(stream:any){//获取视屏流,转换为urlif(video){console.log(stream)video.srcObject=stream;}}vardraw=function(){try{if(backcontext&&video&&back){backcontext.drawImage(video,0,0,back.width,back.height);varurl=back.toDataURL("image/jpeg",0.5);socket.emit('ImgURL',url);}}catch(e){if(=="NS_ERROR_NOT_AVAILABLE"){returnsetTimeout(draw,100);}else{throwe;}}setTimeout(draw,100);}draw();navigator.getUserMedia({video:true,audio:false},success,console.log);setInterval(()=>{if(back){//Canvas的内容转化成dataURI并发送到服务器,0.5为和压缩系数socket.on('receiveData',(url:any)=>{console.log(url)if(this.receive.current){this.receive.current.src=url}})}},100)}5.4websocket服务器实现刚刚介绍过,websocket在服务端的实现方法有许多,接下来简略介绍一下各个方案的实现。Java使用java一般依托于servlet容器,其中Tomcat7、Jetty7及以上版本都开始支持Websocket协议。以上应用对于WebSocket都有各自的实现。但是,它们都遵循RFC6455的通信标准,并且JavaAPI统一遵循JSR356-JavaTMAPIforWebSocket规范。所以,在实际编码中,API差异不大。Spring运用spring框架实现websocket时需要搭建的环境依赖以下jar包:<dependency><groupId>org.springframework</groupId><artifactId>spring-messaging</artifactId></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-websocket</artifactId></dependency>接下来就是创建websocket处理器以及配置websocket:(1)创建websocket处理器:扩展TextWebSocketHandler或BinaryWebSocketHandler,可以将指定的某些方法重新编写。Spring在收到WebSocket事件时,会自动调用事件对应的方法。(2)配置websocket:配置可以使用注解或是xml两种方式,作用是将websocket处理器添加到注册中心。Socket.io服务端API//监听客户端连接,回调函数会传递本次连接的socketio.on(‘connection’,function(socket));//给所有客户端广播消息io.sockets.emit(‘String’,data);//给指定客户端发送消息io.sockets.socket(socketid).emit(‘String’,data);//监听客户端发送的信息socket.on(‘String’,function(data));//给该socket的客户端发送消息socket.emit(‘String’,data);代码展示varapp=require('express')()varhttp=require('http').Server(app)vario=require('socket.io')(http)varport=3001//监听端口号:3001app.get('/',(req,res)=>{ res.sendFile(__dirname+'/index.html')})io.on('connection',socket=>{ console.log('新用户接入') socket.on("disconnect",()=>{ console.log('用户断开连接') })//监听客户端发送的消息socket.on('message',data=>{ console.log('收到数据:',data)io.emit('receiveData',data)})})http.listen(port,()=>{ console.log(`服务器监听本地端口号:${port}`)})

运行结果当运行后台代码时,监听到用户接入行为以及客户端传入的数据,后台显示如下图所示:图5.3后台数据传输当用户断开连接时,后台显示如下图所示:图5.4断开连接显示

连接成功后页面如下图所示(设置接收端比录制端延迟一秒时间):图5.5连接成功页面显示图5.5本章小结本章主要阐述了websocket协议以及websocket如何在客户端、服务端实现直播功能。Websocket协议与HTTP协议其实没有关联,众所周知,HTTP协议是一个无状态协议,而websocket协议能够使得客户端以及服务端保持一个长连接,服务端能够主动、实时向客户端推送数据。另外还拓展了websocket父集socket.io插件的使用,并且在该产品中,主要是使用了该插件来实现功能。尽管本章只介绍了websocket及相关技术,但是实现直播的技术有很多,我们都可以分别去学习并且实践。

6用户信息页面用户信息页面主要包含了用户的昵称/身份显示、收益显示等,收益还提供提现功能,由于不是主要功能,在这里不详谈。主要页面样式如下图所示:图6.1用户信息页面展示6.1个人信息编辑页面该页面主要是简单的昵称、微信号、电话号、头像的修改界面。在开发过程中,该页面与后台数据库之间的信息交换主要是通过axios实现,与此同时,在传递数据较多时,为了代码的简便性以及方便性,就会使用FormData对象发送数据。其中头像的更换功能的实现思路主要是将用于置放头像的div的click事件与隐藏的input(type=file)标签的click相互绑定。当监听到input标签的change事件时,就读取input标签的文件用于更换div中显示的图片并且在点击提交按钮的时候将图片文件传给后台更换。该页面样式如下图所示:图6.2修改信息页面6.2管理栏管理栏主要分为推广管理、会员管理、学习管理,这些icon点开的页面都是一些个人积分、活动介绍的信息或是跳转至第三方页面。在单独的这些页面里面,我们可以查询自己的积分或是团队收益,也可以了解到升级会员的各项权益。基于该部分都是重复性的组件搭建以及样式调试,在此就不再详述。6.3提现栏提现栏是供用户将自己名下的金额提现到支付宝的操作。提现页面内的提现总额是通过页面初始化时调取接口的返回值显示(下图为初始用户无可提现金额)。当用户填写了提现金额以及收款方实名后,点击按钮前端会将两个输入框内的数据传递给后台操作。提现页面样式如下图:图6.3提现申请页面6.4本章小结本章主要是展示了用户信息页面的各个模块,大部分都是页面样式方面的工作,个别需要与后台交互,获取到后台接口的信息在页面显示,这个时候就运用到了axios(基于ajax封装的方法)来获取接口的数据来在页面进行实时更新。

7问题总结7.1页面兼容性在前端编程方面,页面兼容性方面的问题是不可避免的。最浅显的就比如在不同的分辨率设备上页面的显示是否完全、页面排布是否仍然一致,又或是在ios设备、android设备上页面的显示是否一致。这个时候就涉及到要将页面设计成响应式才可以做到兼容。7.1.1页面显示方面在这里就简单阐述一下响应式页面的实现。在开发过程中主要是在css样式方面做工作。在页面布局上,我所用的响应式实现方式主要是以下两种:(1)使用vw、vh、em等百分比长度单位;(2)使用@media(媒体查询):使用媒体查询,可以针对不同大小、不同分辨率的屏幕定义不同的样式,在刷新浏览器重置的过程中,页面会自动根据浏览器的宽高进行新一轮的渲染。如下代码所示:@media(min-width:1024px){//当屏幕分辨率不小于1024px时.cover{width:100%;height:110px;}.coverimg{width:100%;height:110px;border-radius:5px;border-bottom-right-radius:0;border-bottom-left-radius:0;}}7.1.2js事件兼容方面由于每个浏览器使用的内核不同,所以js使用的事件触发有时候也不同。特别是IE浏览器与其他的浏览器之间有一些差异是需要写一些兼容性的代码去解决的。举例说在产生事件的源上,IE是用event.srcElement,在火狐下是用e.target。如下代码部分所示:varevent=window.event||e;varsrcElement=event.srcElement||event.target;如此一来,获得的srcElement就是同时在IE以及火狐浏览器下的事件源。7.2页面性能不仅仅是兼容性,页面性能也是前端工作很需要注重的一个方面。性能主要就是用户的体验性,体现在页面始加载时是否会白屏、页面加载资源(图片、音乐等)是否会卡顿等方面。能够优化页面性能的方法有很多:(1)代码规范方面,如将js代码放在最后面防止页面加载时阻塞、尽量不要使用css表达式等;(2)使用的图片等资源质量尽量不要太大;(3)将页面的一些较大的资源缓存起来,使得下次进入页面的时候不需要再次请求该资源,能够在页面缓存中直接读取数据在页面中显示。在缓存方面,用到的技术主要是cookie以及webstorage这两个。而webstorage比起cookie的主要优势在于webstorage的存储量大、存储时间长以及有许多丰富易用的接口,比如setItem、getItem、removeItem一类。7.3bug记录在开发过程中,难免会遇到许多问题,在这里,主要列举以下几个较为印象鲜明的bug:(1)在信息填写页面中,众所周知,在手机app端,点击输入框底部是会 自动弹出键盘界面的,而键盘界面并不属于视窗范围内,所以这个时候视窗 的高度是会减小的。而在开发过程中,由于没有意识到这个问题,设置了底部按钮fixed在页面底部的话,就会在键盘弹起的时候,将底部按钮也顶在键盘上方,就会使得页面布局混乱,不够美观。解决办法就是利用第一点阐述过的使用媒体查询方法来使得视窗高度发生变化的时候能够监听到,然后改变页面的布局,其实也算是响应式布局的一方面。解决代码如下所示:Html代码:<inputtype="text"className={style.inputBox}onChange={this.handleName}onFocus={this.hideKeyBoard}onBlur={this.showKeyBoard}/>Typescript代码:fixBackContentEmpty(){setTimeout(()=>{window.scrollTo(0,1);},100);}showKeyBoard(){console.log('showKeyBoard');if(isPC)return;this.setState({keyboardShow:true},()=>{fixBackContentEmpty();});}hideKeyBoard(){console.log('hideKeyBoard');if(isPC)return;this.setState({keyboardShow:false});}(2)在电脑端打开直播页面点击“开始录制”按钮之后,启动摄像头,但是在当前页面返回别的页面的时候,摄像头没有关闭,仍然处于开启的状态,解决方法如下://该方法在组件将要卸载时触发componentWillUnmount(){MediaStreamTtotype.stop();}7.4本章小结本章主要介绍了一些在前端开发方面需要注意的兼容性以及性能的影响,并且记录了几个在开发过程中所遇见的bug,希望能给阅读本文的读者一些启发。

参考文献高湧.微课现状分析——以南京晓庄学院为例[D].南京:南京晓庄学院, 2018.荔枝微课.百度百科[DB/OL]./item/%E8%8D%9 4%E6%9E%9D%E5%BE%AE%E8%AF%BE/22422586?fr=aladdin,2019-05-01.千聊.百度百科[DB/OL]./item/%E5%8D%83%E8% 81%8A/19739109?fr=aladdin,2019-05-01.Vscode.百度百科[DB/OL]./item/visual%20studio%20c ode/17514281,2019-05-01.Websocket.百度百科[DB/OL]./item/WebSocket/1953 845?fr=aladdin,2019-05-02.静默虚空.Websocket详解教程[DB/OL]./jingmoxu kong/p/7755643.html,2019-05-02.funnycoderstar.React中组件通信的几种方式[DB/OL].https://segmentfault.c om/a/1190000012361461?utm_source=tag-newest,2019-05-02.JunChow520.Socket.io-简书[DB/OL]./p/4e80b931 cdea,2019-05-03.PimentelV,NickersonBG.Communicatinganddisplayingreal-time dat awithwebsocket[J].IEEEInternetComputing,2012,16(4):45- 53.FetteI,MelnikovA.Thewebsocketprotocol[R].2011.

致谢本设计(论文)是在我的指导老师兼班主任李光平老师的亲切关怀和悉心指导下完成的。他严肃的科学态度、严谨的治学精神、精益求精的工作作风,深深地感染和激励着我。从题目的选择到最终完成,老师都始终给予我细心的指导和不懈的支持。大学生涯最重要的两年,我遇到了李光平老师,您治学严谨,学识渊博,对每一个学生都尽心尽力的去教导,在我们即将迈进社会之际给予了我们非常大的帮助,为我们营造了一种良好的精神氛围。授人以鱼不如授人以渔,置身其间,耳濡目染,潜移默化,使我接受了全新的思想观念,树立了宏伟的学术目标,领会了基本的思考方式。四年的大学生涯即将画上一个句号,但对于我来说只是人生的一个逗号,我将带着四年里在大学学到的知识踏入社会,开启新的征程。感谢大学里的每一位同学,谢谢你们一直以来给我的支持和鼓励,让我的大学生活变得丰富多彩,从你们每个人的身上,我都学习了很多东西。最后,感谢陪同我走了四年的信息工程学院。特别感谢在百忙之中审阅我论文的专家教授和参加答辩的各位老师,请允许我在这里向你们致以最真诚的祝福。附录试听功能部分代码如下:componentDidMount(){this.fetchChannelInfo();this.fetchProductConfig();fixBackContentEmpty();}componentWillUnmount(){this.setState({initialized:false});window.removeEventListener('scroll',this.initTabScroll);}hasFreeLecture(lectures:LectureModel[]){constfreeLectureList:LectureModel[]=[];if(lectures){lectures.map((lecture)=>{if(lecture.lecture_type==='open_lecture'&&lecture.lecture_mode!=='video'){freeLectureList.push(lecture);}});}this.setState({isAnyFree:freeLectureList.length>0,freeLectureList:freeLectureList});}toggleAudioSwitch(){console.log('switch',this.state.audioSwitch);this.setState((state:State)=>({audioSwitch:!state.audioSwitch}));}toggleAudioListDisplay(){console.log('audiolist',this.state.audioListDisplay);this.setState((state:State)=>({audioListDisplay:!state.audioListDisplay}));}closeAudioList(){this.setState({audioListDisplay:false});}setChannelAudio(id:number,mode:string){this.setState({audioId:id,audioMode:mode},()=>{console.log('更新音频',this.state.audioId,this.state.audioMode);});}fetchChannelInfo(){lettoken=getToken();axios.get(`${Config.WK_BASE_URL}/api/channel/${this.state.id}/info`,{data:{isReset:true,isCancelLoading:true},params:{token}}).then((res)=>{const{channel,lectures,role,channel_access,stats_info,share_info}=res.data.data;setDocumentTitle();letchannelInfo:ChannelModel={...channel,is_manager:role.is_manager,is_liveroom_vip:role.is_liveroom_vip,granted:channel_access.granted,popular:stats_info.popular};letlectureList:LectureModel[]=lectures;this.hasFreeLecture(lectureList);lettab=channel_access.granted?1:0;this.setState({initialized:true,channelInfo,lectureList,tab,shareInfo:share_info},()=>{window.addEventListener('scroll',this.initTabScroll);});});}fetchProductConfig(){axios.get(`/index/product_config`,{data:{isCancelLoading:true},params:{product_type:'channel',product_id:this.state.id}}).then((res)=>{const{dist_money,share_url}=res.data.data;this.setState({dist_money,share_url});});}toggleShareMask(){this.setState({showShareMask:!this.state.showShareMask});}toggleTab(tab:number){this.setState({tab});}initTabScroll(){lettabElem=document.querySelector('.'+style.normalTab);if(tabElem&&document&&document.documentElement){this.tabOffsetTop=this.tabOffsetTop>0?this.tabOffsetTop:tabElem.getBoundingClientRect().top;letscrollTop=document.body.scrollTop||document.documentElement.scrollTop;if(scrollTop>this.tabOffsetTop+20){this.setState({isToTop:true});}else{this.setState({isToTop:false});}}}setGranted(){let{channelInfo}=this.state;channelInfo.granted=true;this.setState({channelInfo});}render(){const{tab,channelInfo,shareInfo,showShareMask}=this.state;consttabCls=this.state.isToTop?classNames(style.normalTab,style.normalTabFix):style.normalTab;constshareCls=this.state.isToTop?style.shareFix:style.shareNormal;if(!this.state.initialized){return<Loadingtype="center"/>;}return(<AccountContext.Consumer>{(value)=>(<divclassName={style.page}><Shareaccount={value.account}unsetUrl={true}shareInfo={{title:shareInfo.share_title,desc:shareInfo.share_description,img:shareInfo.share_icon,type:shareInfo.share_type,url:this.state.share_url,dataU

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论