JavaWeb在线聊天系统开发

  • 项目简介
    • 预览
    • 前端实现
      • index.html
      • chat.html
      • chat.css
      • images、assets图片文件
    • 后端实现
      • config
      • controller
      • pojo
    • 服务器配置
      • 开启Redis服务
      • 开启Nginx服务
      • 开启后台Java服务
  • 常见错误解决方法

项目简介

使用前后端分离进行JavaWeb开发多用户在线聊天系统,前端由HTML5**、CSSJavaScript开发,后端系统以Java语言开发。后端系统在本地开发完成后打包放在腾讯云端centOS服务器上不间断运行,可实现任何终端都可访问聊天系统。
具体要使用的技术还有Nginx、redis、第三方框架等。笔者这里通过服务器IP地址进行访问,有需要也可设置通过域名访问系统,欢迎讨论交流。

预览


前端实现

前端的编写主要实现注册页面index.html和聊天页面chat.html,注册页面对账号和密码输入内容进行限制,可通过代码进行自定义限制:

account:[{required:true,message:'请输入账号!', trigger:'blur'},{min:2,max:20,message:'账号信息不少于2个字符且不能超过20个字符', trigger:'blur'}
],
password:[{required:true,message:'请输入密码!', trigger:'blur'},{min:2,max:10,message:'账号信息不少于2个字符且不能超过10个字符', trigger:'blur'}
],

前端数据通过webSocket与服务器进行通信,因此首先得有自己的服务器,服务器可在腾讯云或阿里云进行注册,本系统采用系统8080端口,云服务器为centOS系统,。有了自己的服务器之后在下面的index.html登录页面中需要ip换成自己的服务器ip地址

 //此ip地址需要修改为自己的服务器ip地址
axios.post("http://xx.xx.xx.xx:8080/api/index",this.user)

index.html

前端开发还使用到了element框架、vue框架,登陆页面index.html完整代码如下:

<!--* @Author: liuy* @Date: 2021-1-6 14:30:54* @LastEditTime: 2021-01-06 14:30:29* @LastEditors: Please set LastEditors* @Description: In User Settings Edit* @FilePath: \web\index.html
-->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>QQ注册</title><!--在网页的页签上加入一个小icon图标--><link rel="shortcut icon" href="images/qq.ico" type="image/x-icon"><!--引入register.css文件--><link rel="stylesheet" href="css/register.css"><!--引入饿了么UI的CSS文件--><link rel="stylesheet" href="css/index.css"></head>
<body><!--img src="data:image/jpeg;base64,"--><!--div#left+tab--><div id="left"></div> <!--表单注册区域的div容器--><div id="app"><el-form :model="user" :rules="rules" ref="myform" label-width="100px" class="demo-ruleForm"><el-form-item prop="account"><el-input placeholder="请输入要注册的账号" v-model="user.account"></el-input></el-form-item><el-form-item prop="password"><el-input placeholder="请输入要注册的密码" show-password v-model="user.password"></el-input></el-form-item><el-form-item style="text-align: center;"><input id="faceFile" style="display:none" type="file" @change="showImg"><el-image id="face"  @click="showFile" :src="user.face"></el-form-item><el-form-item><el-button @click="register" style="width: 384px" type="primary">立即注册</el-button></el-form-item></el-form></div><!--引入vue/ajax/饿了么框架--><script src="js/vue.js"></script><!--发送数据包--><script src="js/axios.min.js"></script><script src="js/index.js"></script><!--申明脚本区--><script>var app = new Vue({el: '#app',    //vue框架作用域该app节点内 //数据区域,e1,data,methods是固定写法,内部的变量名和方法名//可以随意取名data: {user:{account: null,password: null,face: 'images/default_face.png'},rules:{account:[{required:true,message:'请输入账号!', trigger:'blur'},{min:2,max:20,message:'账号信息不少于2个字符且不能超过20个字符', trigger:'blur'}],password:[{required:true,message:'请输入密码!', trigger:'blur'},{min:2,max:10,message:'账号信息不少于2个字符且不能超过10个字符', trigger:'blur'}]}},//方法区域methods: {register(){this.$refs['myform'].validate((valid) => {if (valid) {//把要注册的数据发送给java后端console.log(this.user);console.log(this.user.account);//alert('submit!');//127.0.0.1此ip地址表示自己的地址,then表示请求成功后执行的方法axios.post("http://xx.xx.xx.xx:8080/api/register",this.user).then(res => {if(res.data.code == 200){this.$message({message:'注册成功!',type:'success',center:true,showClose:true,onClose:e =>{//保存登陆人信息sessionStorage.setItem("user",this.user.account);//跳转到聊天窗口location = 'chat.html';}});}else{this.$message.error({message: res.data.message});}//console.log(res);})}});},showValue() {alert(this.account);},showFile(){document.querySelector("#faceFile").click();},showImg(e) {//因为this只能在该方法中用,在子方法用不了,所以用这个变量临时保存var vueThis = this;//得到用户选择的文件var v = e.target.files[0];//把它转为base64编码var reader = new FileReader();//对变量v进行转码reader.readAsDataURL(v);//转码完成后,回去执行这个方法reader.onload = function(r){vueThis.user.face = r.target.result;}}}});</script></body>
</html>

chat.html

聊天页面chat.html中也需要将ip地址换为自己服务器的ip地址:

else {//这里需要把ip地址换为自己服务器的ip地址var url = "ws://xx.xx.xx.xx:8080/chat?account=" + account;this.ws = new WebSocket(url);this.ws.onopen = this.doOpen;this.ws.onmessage = this.doMessege;
}

聊天页面chat.html完整代码:

<!--* @Author: liuy* @Date: 2021-01-04 10:25:29* @LastEditTime: 2021-01-08 09:46:52* @LastEditors: Please set LastEditors* @Description: In User Settings Edit* @FilePath: \web\chat.html-->
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Chat WIndow</title><!--在网页的页签上加入一个小icon图标--><link rel="shortcut icon" href="images/bq.png" type="image/x-icon"><!--引入register.css文件--><link rel="stylesheet" href="css/chat.css"><!--引入饿了么UI的CSS文件--><link rel="stylesheet" href="css/index.css">
</head><body><!--div整个网页-->
<div id="web_bg" style="background-image: url('assets/background.jpg');"><div id="app"><div id="main"><div id="left"><div id="records"><div class = "message_line" v-for="r in messageRecords"><div v-if="r.isMe == 0" class="r"><div class="r_left"><img :src="r.user.face" class="record_face"></div><div class="r_right"><div class="nickname">{{r.user.account}}</div><div class="message_bg">{{r.message}}</div></div></div><div v-if="r.isMe == 1" class="rr"><div class="message_bg_me">{{r.message}}</div><div><img :src="r.user.face" class="record_face"></div></div></div></div><div id="tools"></div><div id="contents"><textarea @keydown.enter="sendMessage" v-model="message" id="contents_text"></textarea></div><div id="buttons"><el-button>关闭</el-button><el-button @click="sendMessage" type="primary">发送</el-button></div></div><!--循环好友列表--><div id="right"><div class="online" v-for="f in friends"><img class="face" :src="f.face"><span class="text1">{{f.account.substring(0,12)}}</span><span class="jianbian">{{f.account.substring(12)}}</span></div></div></div></div>
</div><!--引入vue/ajax/饿了么框架--><script src="js/vue.js"></script><!--发送数据包--><script src="js/axios.min.js"></script><script src="js/index.js"></script><script>var app = new Vue({el: '#app',data: {ws: null,message: '',//好友friends: [],messageRecords: [//{ user: { account: 'admin', face: 'images/game.ico' }, message: 'hello', isMe: 1 },//{ user: { account: 'bigpig', face: 'images/default_face.png' }, message: 'nice', isMe: 0 }]},methods: {doOpen() {this.$notify({title: '最新消息',message: 'can you see me?',position: 'bottom-right',//type: 'info'})},sendMessage() {//判断是否输入空格if(this.message.trim()){//发送给后端this.ws.send(this.message);}//发送完数据,清空输入框this.message = '';//给予输入框焦点光标document.getElementById("contents_text").focus();//alert(this.message); },doMessege(res) {var responseEntity = JSON.parse(res.data);//10代表好友列表if (responseEntity.code == 10) {//更新好友列表this.refreshOnlineUser(responseEntity.data);}//20代表好友消息if (responseEntity.code == 20) {//更新聊天消息this.refreshMessage(responseEntity.data, responseEntity.message);}//网页后台输出用户账号  console.log(res.data);},refreshOnlineUser(data) {this.friends = data;},refreshMessage(user, message) {//判断是否是自己发的消息var isMe = (user.account == sessionStorage.getItem('user') ? 1 : 0);this.messageRecords.push({ 'user': user, 'message': message,'isMe' : isMe});//让多页消息时总是显示最新消息this.$nextTick(() =>{document.querySelector('#records').scrollTop = document.querySelector('#records').scrollHeight;});}},//页面挂载的时候会默认执行的方法mounted() {var account = sessionStorage.getItem("user");//如果用户没有登录if (!account) {this.$message({showClose: true,message: '您还没有登录,请先登录ovo',type: 'error',center: true,showClose: true,onClose: function () {location = 'index.html';}});//alert('请先登录');location = 'login.html';} else {var url = "ws://xx.xx.xx.xx:8080/chat?account=" + account;this.ws = new WebSocket(url);this.ws.onopen = this.doOpen;//alert(1);this.ws.onmessage = this.doMessege;}}})</script></body></html>

chat.css

完整代码如下:

@charset "utf-8";
#main{margin:auto;width:800px;height:540px;border:1px solid #ccc;/*边框 1个像素 实线条 灰色*/border-radius:3px;  /*圆角*/box-shadow:0 0 5px #e0e0e0;  /*x轴,y轴 5个大小的阴影*/display:flex;  /*弹性布局,子容器可以并排显示*/
}
#web_bg{position:fixed;top: 0;left: 0;width:100%;height:100%;min-width: 1000px;z-index:-10;zoom: 1;background-color: #fff;background-repeat: no-repeat;background-size: cover;-webkit-background-size: cover;-o-background-size: cover;background-position: center 0;}
#left{width:80%;
}
#right{border-left: 1px solid #ccc;width:20%;overflow-y: auto;overflow-x: hidden;
}
#records{padding: 5px;box-sizing: border-box;overflow-y: auto;/*calc 计算*/height:calc(60% - 1px);border-bottom: 1px solid #ccc;font-size: 12px;font-family: "SF Pro SC", "HanHei SC", "SF Pro Text", "Myriad Set Pro", "SF Pro Icons", "PingFang SC", "Helvetica Neue", "Helvetica", "Arial", sans-serif;
}
#tools{height:5%;}
#contents{height:25%;outline: none;padding:0px 10px;  /*内间距*/box-sizing: border-box;  /*取消padding-box的增大效果*/overflow-y: auto;  /*内容处,添加垂直滚动条*/word-wrap: break-word;  /*兼容其他浏览器*/
}
#buttons{    height:10%;text-align: right;padding-right:10px;box-sizing: border-box;
}
#contents_text{width:calc(100% - 4px);height:calc(100% - 20px);/*无边框*/border: none;/*不可拖动大小*/resize: none;outline: none;background-color: transparent;}
*::-webkit-scrollbar {width: 8px;height: 20px;
}*::-webkit-scrollbar-thumb {border-radius: 10px;background: #9d9d9d;
}
.online{/*行高*/line-height: 30px;font-family: "SF Pro SC","HanHei SC","SF Pro Text","Myriad Set Pro","SF Pro Icons","PingFang SC","Helvetica Neue","Helvetica","Arial",sans-serif;font-size: 14px;
}
.face{width: 20px;height: 20px;border-radius: 50%;/*垂直对齐文本*/vertical-align: middle;/*距离右边6个像素*/margin-right:6px;
}
.text1{width:90px;display: inline-block;user-select: none;
}
.jianbian{/*谷歌渐变效果*/user-select: none;position: relative;left: -1px;width: 10px;display: inline-block;background: linear-gradient(to right,black,white);-webkit-text-fill-color: transparent;-webkit-background-clip: text;
}
.record_face{width: 30px;height: 30px;border-radius: 50%;vertical-align: top;
}
.nickname{color: #666;}.r{display: flex;float: left;
}.rr{display: flex; float: right;
}.r_left{width: 30px;height: 30px;
}
.r_right{margin-top: 10px;}.message_bg{background-color: #ccc;padding: 10px;border-radius: 5px;/*让消息气泡横向不溢出*/word-wrap:break-word;max-width: 560px;display:inline-block;
}.message_bg_me{background-color:palegreen;padding: 10px;border-radius: 5px;/*让消息气泡横向不溢出*/word-wrap:break-word;max-width: 560px;display:inline-block;
}
.message_line{clear:both;height:45px;
}

images、assets图片文件

这里我将聊天背景图和注册页面图片分成了两个图片文件,分别是images文件夹和assets文件夹,如果需要修改图片可替换图片文件,并在index.html和chat.html中修改图片索引:

<!--这里修改图片索引-->
<div id="web_bg" style="background-image: url('assets/background.jpg');">

我的图片github地址:

https://github.com/letme5/letme5.github.io

后端实现

后台使用java开发,使用了SpingBoot、WebSocket等框架。
分为config、controller、pojo三个package。

config

config下有三个类,CrossConfig用于跨域访问,RedisConfig用于后台数据管理,WebSocketConfig用于前后端交互连接。

CrossConfig类:

package com.seecen.tencent.config;import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** @author liuyo* 跨域访问*/
@Configuration
public class CrossConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry){registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET","POST","DELETE","PUT","HEAD","OPTIONS").allowedHeaders("*");}}

**RedisConfig类:

package com.seecen.tencent.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;/*** @author liuy* 配置类,Redis默认set只能存储String类型,序列化后可以存储一个USer对象的类型*/
@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory factory){RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();/*指明要连接的数据库*/redisTemplate.setConnectionFactory(factory);/**序列化,将内存中的对象转换为二进制类型*/redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());return redisTemplate;}
}

WebSocket类:

package com.seecen.tencent.config;import com.seecen.tencent.controller.ChatController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.server.HandshakeInterceptor;
import java.util.Map;/*** @author 93193*/
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {@AutowiredRedisTemplate<String,Object> redisTemplate;/**前端怎么和后端进行交互链接*/@Overridepublic void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {// 前端通过ip:port/chat可以访问后台registry.addHandler(new ChatController(redisTemplate), "/chat").addInterceptors(new HandshakeInterceptor() {@Overridepublic boolean beforeHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {ServletServerHttpRequest request = (ServletServerHttpRequest) serverHttpRequest;// 获取前端用户传递过来的账户名称String account = request.getServletRequest().getParameter("account");map.put("account", account);return true;}@Overridepublic void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {}})// 所有的前端可以访问。跨域请求开放.setAllowedOrigins("*");}}

controller

ChatController类:

package com.seecen.tencent.controller;import com.fasterxml.jackson.databind.ObjectMapper;
import com.seecen.tencent.pojo.ResponseEntity;
import com.seecen.tencent.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.AbstractWebSocketHandler;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;/*** @author liuyo*/
public class ChatController extends AbstractWebSocketHandler {/**ctrl+O选择覆盖的方法*/CopyOnWriteArrayList<WebSocketSession> users =new CopyOnWriteArrayList<>();ObjectMapper mapper = new ObjectMapper();@AutowiredRedisTemplate<String,Object> redisTemplate;public ChatController(RedisTemplate<String, Object> redisTemplate) {this.redisTemplate = redisTemplate;}@Override  /**重写验证*/public void afterConnectionEstablished(WebSocketSession session) throws Exception {//用集合数组保存所有在线用户Object account = session.getAttributes().get("account");System.out.println(account+" join the chat");//保存当前登录用户users.add(session);//把所有在线用户同步给所有前端sendAllOnlineUser();}private void sendAllOnlineUser() throws Exception {List<User> list = new ArrayList<>();//遍历users集合users.forEach(user -> {String account = user.getAttributes().get("account").toString();list.add((User) redisTemplate.opsForValue().get(account));});ResponseEntity entity = new ResponseEntity(10, "好友列表", list);// 把entity转换为json给前端String jsonStr = mapper.writeValueAsString(entity);//遍历user集合,将在线用户发送给前端每个用户sendMsg(jsonStr);}/**封装发送消息模块*/private void sendMsg(String message){users.forEach(user -> {try {user.sendMessage(new TextMessage(message));} catch (IOException e) {e.printStackTrace();}});}@Overridepublic void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {//当前发送者User user = (User)redisTemplate.opsForValue().get(session.getAttributes().get("account"));//当前发送者发送的消息String msg = message.getPayload().toString();ResponseEntity entity = new ResponseEntity(20,msg,user);//把java对象转换为json字符给前端{key1:value1,key2:value2}String jsonStr = mapper.writeValueAsString(entity);sendMsg(jsonStr);System.out.println("new message: "+message.getPayload().toString());}@Overridepublic void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {System.out.println("an error has occured__by liuyong");}@Overridepublic void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {System.out.println("User refreshes, resulting in disconnection"+users);//把退出的人从数组中删除users.remove(session);sendAllOnlineUser();}
}

UserController类:

package com.seecen.tencent.controller;import com.seecen.tencent.pojo.ResponseEntity;
import com.seecen.tencent.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;/*** @author liuy* Servlet/controller* 前后端的桥梁* 负责接收前端发送过来的请求* 然后计算后得到结果,响应给到后端* RestController-注册为控制器并实例化**/
@RestController
public class UserController {@AutowiredRedisTemplate<String,Object> redisTemplate;/**与前端post方式相同,精确定位到要访问的方法*/@PostMapping("/api/register")/**返回类型、方法名、形参*/ResponseEntity register(@RequestBody User user){if(redisTemplate.hasKey(user.getAccount())){return ResponseEntity.ERROR("要注册的账户已经存在,请更换!");}else{redisTemplate.opsForValue().set(user.getAccount(),user);System.out.println(user.getAccount());System.out.println(user.getPassword());System.out.println(user.getFace());return ResponseEntity.OK();}}@GetMapping("/face")public String getFace(String account){if(redisTemplate.hasKey(account)){User user = (User) redisTemplate.opsForValue().get(account);return user.getFace();}else{return  null;}}}

pojo

ResponseEntity类:

package com.seecen.tencent.pojo;/*** @author liuy* 服务器响应数据对象*/
public class ResponseEntity {/**响应状态码*/int code;/**响应的消息*/String message;/**响应数据体*/Object data;public ResponseEntity(){}/**Alt+insert快速创建构造方法*/public ResponseEntity(int code,String message,Object data){this.code=code;this.message=message;this.data=data;}public static ResponseEntity OK(){ResponseEntity responseEntity = new ResponseEntity();//状态码200表示成功responseEntity.code =200;responseEntity.message = "success";return responseEntity;}public static ResponseEntity ERROR(String s){ResponseEntity responseEntity = new ResponseEntity();//状态码500表示失败responseEntity.code =500;responseEntity.message = "账户已存在,请检查用户名";return responseEntity;}public int getCode() {return code;}public void setCode(int code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}
}

User类:

package com.seecen.tencent.pojo;import java.io.Serializable;/*** @author 93193*/
public class User implements Serializable {String account;String password;String face;public String getAccount() {return account;}public void setAccount(String account) {this.account = account;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public String getFace() {return face;}public void setFace(String face) {this.face = face;}@Overridepublic String toString() {return "User{" +"account='" + account + '\'' +", password='" + password + '\'' +", face='" + face + '\'' +'}';}
}

服务器配置

做完以上步骤以后,就可以进行服务器配置了,由于我们后端是用java语言编写,因此在服务器上首先要装要配置好java环境,jdk可在互联网搜索下载,安装好后使用java -version命令查看java环境是否配置成功,我这里安装的是jdk1.8.0版本:

安装好java环境后还需要在服务器安装Redis、Nginx实现数据管理和访问操作,安装路径都为/usr/local。
Redis、Nginx、Maven安装包:

https://pan.baidu.com/s/1JL85E2h3sN_eUjLOPsceWg
提取码:1234

开启Redis服务

安装好Redis、Nginx之后,首先需要开启Redis服务,服务器上使用命令:

cd /usr/local/redis-3.2.9
redis-server redis.conf

开启Nginx服务

此时我们使用命令切换到Nginx安装目录的html目录下:

cd /usr/local/nginx/html

将我们写的前端页面全部文件拷贝到该目录下,目录下原先有的index.html文件将被替换。

此时我们需要启动Nginx服务,使用命令:

cd /usr/local/nginx/sbin
./nginx

开启后台Java服务

接着我们要将Java项目使用Maven进行打包,打包完成后将jar包包拷贝至/usr/local路径下,此时使用命令在服务器运行后端服务:

java -jar tencent-0.0.1-SNAPSHOT.jar //前台运行

java -jar tencent-0.0.1-SNAPSHOT.jar & //后台运行

出现此界面运行成功:

此时在浏览器输入我们服务器ip就能成功访问我们的web页面啦!

最后附上笔者的代码文件:

前端:https://github.com/letme5/letme5.github.io
后端:https://pan.baidu.com/s/1JL85E2h3sN_eUjLOPsceWg (提取码:1234 )

常见错误解决方法

  1. 检查redis 数据库是否有打开:

redis-cli

如果显示127.0.0.1:6379表示redis成功打开;显示no connect 就代表redis没有启动,需要先启动redis数据库, 启动方式:

cd /usr/local/redis-3.2.9
redis-server redis.conf

  1. 检查java后台程序是否启动,服务器输入:

jps

查看是否有jar的进程,如果没有,通过命令cd进入到你放置jar包的目录下,启动java服务:

java -jar (name).jar

  1. 启动前端页面服务器,我们放置的在Nginx服务器中如果访问 http://xxx.xxx.xxx.xxx/显示无法访问,那么大概率没有启动Nginx,服务器使用命令开启Nginx服务:

cd /usr/local/nginx/sbin
./nginx

4.如果报错显示一个 /var/run/nginx/nginx.pid not found…这个代表启动的时候会在/var/run/nginx这个目录下生成一个进程ID文件,没有的话我们创建即可,使用命令:

mkdir -p /var/run/nginx

创建完成再次启动:

./nginx

JavaWeb在线聊天系统开发相关推荐

  1. 基于SpringBoot开发的Java web在线聊天系统,即时通讯通信系统,基于IDEA开发

    目录 简介 主要实现的功能有: 主要功能截图 温馨提示 简介 今天发布的是一款由Springboot+MySQL+SSM实现的Java web在线聊天系统,适合大家在网上聊天,加好友等操作,极大的方便 ...

  2. 基于SSM实现在线聊天系统

    基于SSM实现在线聊天系统 本聊天系统基于SSM的实现在线聊天功能,通过WEBSOCKET实现消息发送,可以实现在线实时聊天互动,并统计时时在线人数.聊天时可以发送文字.图片.表情等操作,并可以进行清 ...

  3. 陪玩视频聊天系统开发,升级与更新功能的实现

    随着科技的不断发展,陪玩视频聊天系统开发中也会不断的更新和优化各种功能模块,陪玩视频聊天系统升级与更新功能的实现关系着用户的使用体验,所以,本文将讲解陪玩视频聊天系统开发的升级与更新. 一般而言在陪玩 ...

  4. JavaWeb在线考试系统(简单版)

    JavaWeb在线考试系统 作者简介 作者名:编程界明世隐 简介:CSDN博客专家,从事软件开发多年,精通Java.JavaScript,博主也是从零开始一步步把学习成长.深知学习和积累的重要性,喜欢 ...

  5. 基于Springboot+vue的在线聊天系统

    [辰兮要努力]:hello你好我是辰兮,很高兴你能来阅读,昵称是希望自己能不断精进,向着优秀程序员前行! 博客来源于项目以及编程中遇到的问题总结,偶尔会有读书分享,我会陆续更新Java前端.后台.数据 ...

  6. 聊天系统服务器端类图怎么画,在线聊天系统的设计与实现.docx

    PAGE 在线聊天系统的设计与实现 本科毕业设计 目录TOC \o "1-3" \h \u 目录 1 前 言 1 2. 需求分析 2 2.1 系统运行环境需求 2 2.2 模块功能 ...

  7. 计算机毕业设计Java宁夏中卫城市风采在线系统开发(源码+系统+mysql数据库+lw文档)

    计算机毕业设计Java宁夏中卫城市风采在线系统开发(源码+系统+mysql数据库+lw文档) 计算机毕业设计Java宁夏中卫城市风采在线系统开发(源码+系统+mysql数据库+lw文档) 本源码技术栈 ...

  8. 计算机毕业设计-ssm饮用水配送管理系统代码-javaweb在线配送桶装水管理系统-水站配送管理java项目

    计算机毕业设计-ssm饮用水配送管理系统代码-javaweb在线配送桶装水管理系统-水站配送管理java项目 注意:该项目只展示部分功能,如需了解,评论区咨询即可. 作者:IT跃迁谷 1.开发环境 开 ...

  9. javaWeb在线考试系统

    javaWeb在线考试系统 系统介绍 系统实现 考生权限 登录页 菜单主页 在线考试 考试成绩查询 考生密码修改 退出系统 管理员权限 登录页面 成绩管理 考试信息管理 试卷管理 试题管理 数据库设计 ...

  10. 基于JavaWeb在线书城系统

    1.简介 项目名称:在线书城系统 ---- <咖啡书城> 用户:普通用户,管理员 说明:系统属于非商用版本. 2.技术栈 Java Shiro Swagger-UI mybatis JWT ...

最新文章

  1. excel文件数据导入mysql数据库中_将excel里面的数据导入mysql数据库中
  2. 2018 Multi-University Training Contest 9 杭电多校第九场 (有坑待补)
  3. 实战渗透之一个破站日一天
  4. java resource放入的文件没有生成在classes中_快速部署版@开源在线考试系统一键生成各种题型试卷且实时判卷...
  5. 线性表----链式表
  6. linux两个数字正则,正则表达式-Linux readelf显示具有不同数字系...
  7. Juniper Olive动态路由RIP配置案例
  8. ci/cd heroku_在GitLab上设置CI / CD以在Heroku上部署Python Flask应用程序
  9. 【转】什么是磁珠(Ferrite Bead 即 FB)
  10. 数据持久化基础知识——属性列表
  11. android使用FFmpeg解码MP4中的音频并使用AudioTrack播放
  12. 计算机诗人 原理,自动作诗器,藏头诗软件生成器原理是什么?
  13. java中调用cmd命令被阻塞无法返回和继续执行
  14. 宝马推出电动自行车,最大续航300公里
  15. PS小白怎么学会更换材质效果
  16. 我的web前端工作日记2------web前端工作的一天
  17. python画图函数
  18. Python 关于时间处理之时间相减
  19. FL STUDIO宿主软件v20.9中文版使用技巧心得
  20. ANSYS 添加PCB板材料 FR-4

热门文章

  1. eclipse运行java快捷键,eclipse常用快捷键
  2. 如何用虚拟机安装服务器系统教程,手把手教你虚拟机如何安装系统
  3. Java的jps命令使用详解
  4. Java入门到精通(六)
  5. pycharm2020版本以上中文版教程
  6. Java数据类型转换超详解
  7. 《信号与系统学习笔记》—线性反馈系统(一)
  8. c语言出100道计算题,C语言例题100道
  9. java2实用教程第四版pdf下载_Java 2实用教程(第4版)
  10. 算法设计与分析期末复习题