社区微信群开通啦,扫一扫抢先加入社区官方微信群
社区微信群
以前用flex做过中国象棋对战版CS架构的,没用到websocket,消息推送使用定时刷新不断请求服务器,比较耗资源,现在刚接触websocket,闲来无事就重写个小项目消遣下.本人前端菜鸟,Ext也是刚接触,画的界面比较丑,勿喷.
先上截图~
登陆界面,没有用户可以注册一个,用的是sqlite数据库
聊天主界面,可以选择跟在线的人聊天,也可以点群消息,广播消息给所有人
游戏大厅及游戏主界面.右边显示系统提示信息 也可以在这里跟对手聊天~
部分代码:
导入springboot所用jar:pom文件如下:
4.0.0com.donggemyweb0.0.1-SNAPSHOTorg.springframework.bootspring-boot-starter-parentpom1.5.3.RELEASEimportorg.springframework.bootspring-boot-starter-weborg.mybatis.spring.bootmybatis-spring-boot-starter1.3.0org.springframework.bootspring-boot-starter-securityorg.springframework.bootspring-boot-starter-websocketorg.xerialsqlite-jdbcorg.apache.maven.pluginsmaven-compiler-plugin1.71.7org.springframework.bootspring-boot-maven-pluginZIPcom.dongge.Applicationrepackage
websocket配置:
/**
* @author 东哥 2017年6月1日
*
*/
@Configuration
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
/**
* @author 东哥 2017年6月1日
*
*/
@ServerEndpoint(value = "/chat", configurator = GetHttpSessionConfig.class, encoders = {
MsgEncoder.class }, decoders = { MsgDecoder.class })
@Component
public class ChatController {
public static Set<ChatController> CHAT_SET = new CopyOnWriteArraySet<ChatController>();
private static List<User> onlineUsers = new ArrayList<User>();
private final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
private Session session;
private User user;
@OnOpen
public void openConnection(final Session session, final EndpointConfig config) {
this.session = session;
final HttpSession httpsession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
user = (User) httpsession.getAttribute("login_user");
onlineUsers.add(user);
CHAT_SET.add(this);
System.out.println(user.getNickName() + "进入聊天室");
onlineNotify(user.getNickName() + "进入聊天室");
}
@OnClose
public void close() {
CHAT_SET.remove(this);
onlineUsers.remove(user);
System.out.println(user.getNickName() + "离开聊天室");
onlineNotify(user.getNickName() + "离开聊天室");
}
@OnMessage
public void handlerMessage(final ClientMessage message, final Session session) {
final PushMessage pushMsg = new PushMessage();
pushMsg.setFromUser(user.getUsername());
pushMsg.setType(message.getType());
if ("chat".equalsIgnoreCase(message.getType())) {
pushMsg.setMessage("<span style='color:green;font-size:8px'>" + user.getNickName() + " "
+ sdf.format(new Date()) + "</span><p>" + message.getMessage() + "</p>");
}
pushMsg.setData(message.getData());
final String toUser = message.getToUser();
if (StringUtils.isEmpty(toUser) || "all".equalsIgnoreCase(toUser)) {// 推送给所有人
pushMsg.setToUser("all");
broadcast(pushMsg);
} else {// 推送给自己和对方
pushMsg.setToUser(toUser);
sendData(pushMsg);
for (final ChatController item : CHAT_SET) {
if (toUser.equals(item.user.getUsername())) {
item.sendData(pushMsg);
}
}
}
}
@OnError
public void error(final Session session, final Throwable error) {
System.out.println("发生错误:" + error.getMessage());
}
private void onlineNotify(final String msg) {
final PushMessage message = new PushMessage();
message.setType("onlineUsers");
message.setData(onlineUsers);
message.setMessage("<span style='color:purple;font-size:8px'>" + msg + "</span><br/>");
message.setToUser("all");
broadcast(message);
}
private void broadcast(final PushMessage message) {
for (final ChatController item : CHAT_SET) {
item.sendData(message);
}
}
public void sendData(final PushMessage data) {
try {
session.getBasicRemote().sendObject(data);
} catch (final IOException e) {
e.printStackTrace();
} catch (final EncodeException e) {
e.printStackTrace();
}
}
}
象棋websocket入口
/**
* @author 东哥 2017年6月13日
*
*/
@ServerEndpoint(value = "/chess", configurator = GetHttpSessionConfig.class, encoders = {
MsgEncoder.class }, decoders = { MsgDecoder.class })
@Component
public class ChessController {
public static final Map<String, ChessRoom> ROOM_MAP = new HashMap<String, ChessRoom>();
private User user;
private Session session;
@OnOpen
public void openConnection(final Session session, final EndpointConfig config) {
this.session = session;
final HttpSession httpsession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
user = (User) httpsession.getAttribute("login_user");
final String roomId = session.getRequestParameterMap().get("roomId").get(0);
session.getUserProperties().put("roomId", roomId);
ChessRoom room = null;
if (ROOM_MAP.get(roomId) != null) {
room = ROOM_MAP.get(roomId);
room.getUserList().add(user);
room.getSessionList().add(session);
} else {
room = new ChessRoom(roomId);
final List<User> userList = new ArrayList<User>();
userList.add(user);
room.setUserList(userList);
final List<Session> sessionList = new ArrayList<Session>();
sessionList.add(session);
room.setSessionList(sessionList);
ROOM_MAP.put(roomId, room);
}
final PushMessage pushMsg = new PushMessage();
pushMsg.setType("room_msg");
pushMsg.setMessage(user.getNickName() + "进入房间");
pushMsg.setData(room.getUserList());
room.braodcast(pushMsg);
notifyAllUsers();
}
private void notifyAllUsers() {
final List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
for (final String key : ROOM_MAP.keySet()) {
final ChessRoom room = ROOM_MAP.get(key);
final Map<String, Object> item = new HashMap<String, Object>();
item.put("roomId", key);
item.put("userList", room.getUserList());
data.add(item);
}
final PushMessage pushMsg = new PushMessage();
pushMsg.setType("room_msg");
pushMsg.setData(data);
for (final ChatController chat : ChatController.CHAT_SET) {
chat.sendData(pushMsg);
}
}
@OnClose
public void close() {
final String roomId = (String) session.getUserProperties().get("roomId");
if (ROOM_MAP.get(roomId) != null) {
final ChessRoom room = ROOM_MAP.get(roomId);
room.getUserList().remove(user);
room.getSessionList().remove(session);
final PushMessage pushMsg = new PushMessage();
pushMsg.setType("room_msg");
pushMsg.setMessage(user.getNickName() + "离开了房间");
pushMsg.setData(room.getUserList());
room.braodcast(pushMsg);
if (room.getUserList().isEmpty()) {
ROOM_MAP.remove(roomId);
}
}
session.getUserProperties().remove("roomId");
notifyAllUsers();
}
@OnMessage
public void handlerMessage(final ClientMessage message, final Session session) {
final PushMessage pushMsg = new PushMessage();
pushMsg.setFromUser(user.getUsername());
pushMsg.setType(message.getType());
pushMsg.setData(message.getData());
pushMsg.setMessage(message.getMessage());
final String roomId = (String) session.getUserProperties().get("roomId");
if (ROOM_MAP.get(roomId) != null) {
final ChessRoom room = ROOM_MAP.get(roomId);
room.braodcast(pushMsg);
}
}
@OnError
public void error(final Session session, final Throwable error) {
System.out.println("发生错误:" + error.getMessage());
}
聊天主窗口创建的时候建立聊天websocket连接
initComponent : function() {
websocket = new WebSocket('ws://' + serverIp + '/chat');
websocket.onmessage = onmessage;
window.onbeforeunload = function() {
if (websocket != null) {
websocket.close();
}
}
this.callParent(arguments);
}
function onmessage(event) {
var data = Ext.JSON.decode(event.data);
if (data.type == 'onlineUsers') {
onlineUsers = data.data;
refreshOlUsers(onlineUsers);
setGroupWinMsg(data.message);
} else if (data.type == 'chat') {
var toUser = data.toUser == currentUser.username ? data.fromUser
: data.toUser;
var nickName = getUserByUsername(toUser).nickName;
var node = {
id : toUser,
text : nickName
};
showChatWin(node, data.message);
} else if (data.type == 'room_msg') {
var roomMap = data.data;
if (gamehall) {
gamehall.setRoomPanelInfo(roomMap);
}
}
}
function onWinRender(win) {
var canvas = Ext.query('#' + win.id + ' canvas')[0];
drawer = new ChessDrawer(canvas);
drawer.init();
canvas.addEventListener('click', clickCanvas);
chessSocket = new WebSocket('ws://' + serverIp + '/chess?roomId='
+ win.roomId);
chessSocket.onmessage = onChessMsg;
win.on('close', function() {
if (chessSocket != null) {
chessSocket.close();
}
});
window.onbeforeunload = function() {
if (chessSocket != null) {
chessSocket.close();
}
}
}
function onChessMsg(event) {
var data = Ext.JSON.decode(event.data);
if (data.message) {
room.setMsg(data.message);
}
if (data.type == 'room_msg') {
roomUsers = data.data;
if (roomUsers && roomUsers.length == 2) {
readyable = true;
roomUsers[0].isfirst = true;
roomUsers[1].isfirst = false;
for ( var i in roomUsers) {
if (currentUser.username == roomUsers[i].username) {
isfirst = roomUsers[i].isfirst;
turn = isfirst ? 1 : 0;
}
}
} else {
readyable = false;
selfReady = false;
opReady = false;
isfirst = false;
isplay = false;
room.down('button[name=ready]').enable();
room.down('button[name=lose]').disable();
}
} else if (data.type == 'chat') {
//
} else if (data.type == 'chess') {
moveChess(data.data.x, data.data.y, data.data.ex, data.data.ey);
isplay = !isplay;
judge();
} else if (data.type == 'ready') {
var t = data.data.turn;
if (t != turn) {
Ext.MessageBox.alert('提示', '对方已准备');
opReady = true;
}
if (selfReady && opReady) {
isplay = isfirst;
room.down('button[name=draw]').enable();
room.down('button[name=lose]').enable();
}
} else if (data.type == 'gameover') {
var t = data.data.turn;
if (t != turn) {
Ext.MessageBox.alert('提示', data.data.opAlertMsg);
}
isplay = false;
selfReady = false;
opReady = false;
isfirst = !isfirst;
turn = isfirst ? 1 : 0;
room.down('button[name=ready]').enable();
room.down('button[name=draw]').disable();
room.down('button[name=lose]').disable();
} else if (data.type == 'draw') {
var t = data.data.turn;
if (t != turn) {
Ext.MessageBox.confirm('提示', '对手选择和棋,是否同意', function(bid) {
var agree = false, msg = '';
if ('yes' == bid) {
agree = true;
msg = '同意和棋请求,游戏结束';
} else {
agree = false;
msg = '不同意和棋请求';
}
var data = {
type : 'draw_result',
data : {
turn : turn,
agree : agree
},
message : currentUser.nickName + msg
};
chessSocket.send(Ext.JSON.encode(data));
});
}
} else if (data.type == 'draw_result') {
if (data.data.agree) {
isplay = false;
selfReady = false;
opReady = false;
isfirst = !isfirst;
turn = isfirst ? 1 : 0;
room.down('button[name=ready]').enable();
room.down('button[name=draw]').disable();
room.down('button[name=lose]').disable();
} else {
var t = data.data.turn;
if (t != turn) {
Ext.MessageBox.alert('提示', '对方不同意您的和棋请求');
}
}
}
}
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!