平时经常性的使用聊天软件如QQ,微信,或是游戏里各个区的公共频道,于是突发奇想,想要自己搞一个简易版聊天项目,所以现在开搞起来。
1.想要进行聊天,势必需要有人才能聊起来,因此需要用户,且用户可以注册,登录(注册用户,打开主页,看到登录页面) 2.登录成功之后,就可以进入主页面 3.主页面显示现在用户关注的频道列表,即关注之后,才可以在此频道发言。 4.点击其中一个频道之后,就可以在此频道发消息 5.在频道中还可以看到其他人的发言,即公共消息群内人均可以看到 6.当用户退出,在他下一次登录之后,可以查阅在他不在的这段时间当中,大家都发了生命消息。
要想实现网页聊天,则需要一个应用层协议进行数据传输 1号备选协议HTTP:
http可以实现消息推送√但http适合网页聊天吗? 答案是,可以实现,但耗费资源较为多,且效率低。 http是典型的一问一答模式,即如果客户端没有主动向服务器请求,服务器是不会给予响应的。 但http中又有轮询(规定一定周期:1s一次询问,让客户端向服务器发送请求),这样看起来就像是服务器主动给客户端推送消息一样,但本质上还是一问一答,只不过问的那一步被隐藏了起来。 但这种消息推送效率相当低,因为没有用户会不间断的发消息,客户端大部分情况都是没有新消息的,所以在没有消息发送时,问服务器 就是在做无用功。且如果采用短轮询连接成本也相当大。 因此http不适合用于聊天系统。
http适合消息推送×2号备选协议WebSocket:
websocket可以实现消息推送√那websocket适合网页聊天吗? 首先websocket是一个应用层协议,其次websocket可以完成不问就答 。 websocket允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
websocket适合消息推送√好啦~ 协议选择完毕~~
WebSocket 是独立的、创建在 TCP 上的协议。 Websocket 是基于Http协议.HTML5 Websocket 通过HTTP/1.1 协议的101状态码进行握手。 为了创建Websocket连接,需要通过浏览器发出请求,之后服务器进行回应,这个过程通常称为“握手”(handshaking)。
由于以上原因可以得出,WebSocket是需要通过升级http协议才能进行使用。
升级协议:客户端尝试针对服务器发送ws://这样的url请求时,此时发的仍然是一个HTTP请求,但是请求中会带有Upgrade字段来请求升级协议,服务器端如果同意升级,就会返回一个101状态码的响应报文。
此时websocket连接建立完毕,就可以传输数据。
客户端使用websocket也需要url来指定服务器的位置 这个url是以ws://开头,ws是websocket的缩写
在使用WebSocket
第一步就是要引入第三方依赖,使用maven进行管理 配置 :
<!-- https://mvnrepository.com/artifact/javax.websocket/javax.websocket-api --> <dependency> <groupId>javax.websocket</groupId> <artifactId>javax.websocket-api</artifactId> <version>1.1</version> <scope>provided</scope> <!--表示开发时需要使用,部署到Tomcat上的时候,就不需要带此jar包(tomcat内置这个jar包)--> </dependency>第二步使用注解**@ServletEndpoint**
在web开发中,可以使用@ServletEndpoint注解修饰指定的类,同时在注解中使用value参数来指定一个具体的路径 后续html页面就可以通过这个路径来访问到服务器
1.设计客户端和服务端 2.服务器如何给客户端返回消息
服务器端收到客户端发的消息,就会触发onMessage函数,调用sendText就把数据返回给了浏览器 浏览器收到服务器的响应之后,就会触发onmessage函数,从而打印收到的内容session.getBasicRemote().sendText(""); //把一个文本数据写回到浏览器 //需要程序员主动调用,调用这个方法就能写回数据,无需客户端先发送请求
websocket.send()给服务器发送数据
实体有: User(用户信息) Channel(频道) Massage(消息)
User和Channel:多对多(但由于还未实现关注频道功能,暂时的将其简化为任何用户都可进入所有频道) User和Message:一对多 Channel和Message:一对多(未实现消息群发)
确定客户端都能给服务端发哪些种类的请求。 服务器收到请求之后该返回什么样的响应。
请求格式 POST /register { name:xxx, password:xxx, nickName:xxx } 响应格式 HTTP/1.1 200 OK { ok:1, //1表示成功,0表示失败(此处约定方式只是常见的方式之一当然也可以约定成其他格式) reason:xxx //如果失败,reason就是一个具体的失败原因 }
请求格式 POST /login { name:xxx, password:xxx } 响应格式 HTTP/1.1 200 OK { ok:1, reason:xxx, userId:1, name:xxx, nickName:xxxx }
请求格式 GET / login Cookie:JSESSION=XXXXX 响应格式 HTTP /1.1 200 OK { ok:1, reason:xxx, userId:1, name:xxx, nickName:xxx }
未实现!
请求格式 POST /channel { channelName:xxx } 响应格式 HTTP/1.1 200 OK { ok:1, reason:xxxx }
请求格式 GET /channel 响应格式 HTTP/1.1 200 OK [ { channelID;1, channelName:“ASRM” }, { channelID;2, channelName:“ASMR” } ]
请求格式 DELETE /channel?channlId=1 响应格式 HTTP/1.1 200 ok{ }
这就不是HTTP协议了 ws://[ip]:[port]/message/{userId} 每个登录中的用户,都需要有自己的连接,把连接之间使用userId来区分。
为了简单起见,把发送和接受格式统一成一样的了(按理说应该不一样) JSON:当前这个message是通过websocket来传输,而不是HTTP协议了。 { userId:1,//消息是谁发的 nickName:xxx,//消息发送者的昵称 channelId:xxx,//消息要往哪个频道发送 content:“123asd”,//消息内容 }
网上聊天室测试