This commit is contained in:
2025-06-27 21:03:23 +08:00
parent 0f29dccec4
commit 54dc7ba173
5 changed files with 188 additions and 11 deletions

175
Client/a.html Normal file
View File

@@ -0,0 +1,175 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>游戏方块容器</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body, html {
height: 100%;
overflow: hidden;
background-color: #f0f0f0; /* 页面背景色 */
}
.grid-container {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(4, 1fr);
gap: 15px;
width: min(100vw, 100vh); /* 取视口宽高的较小值 */
height: min(100vw, 100vh); /* 确保容器是正方形 */
padding: 20px;
background-color: white; /* 容器背景为白色 */
margin: 0 auto; /* 水平居中 */
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* 完全居中 */
}
.grid-item {
background-color: white; /* 大方块背景为白色 */
border: 2px solid #e0e0e0; /* 柔和的边框 */
border-radius: 6px;
display: flex;
flex-wrap: wrap; /* 允许内部小方块换行 */
position: relative; /* 为内部元素定位做准备 */
overflow: hidden; /* 隐藏超出部分 */
/* 不再需要aspect-ratio因为grid布局会自动保持正方形 */
}
/* 内部小方块样式 */
.inner-square {
width: 25%; /* 4x4网格每个占25%宽度 */
height: 25%; /* 4x4网格每个占25%高度 */
border: 1px solid #f5f5f5; /* 浅色边框分隔 */
box-sizing: border-box;
}
/* 状态指示器 */
.status-indicator {
position: absolute;
top: 5px;
right: 5px;
width: 10px;
height: 10px;
border-radius: 50%;
background-color: #ccc; /* 默认灰色(未连接) */
}
.status-connected {
background-color: #2ecc71; /* 连接成功时绿色 */
}
.status-error {
background-color: #e74c3c; /* 错误时红色 */
}
</style>
</head>
<body>
<div class="grid-container">
<script>
document.addEventListener('DOMContentLoaded', () => {
const container = document.querySelector('.grid-container');
// 创建16个大方块容器
for (let i = 1; i <= 16; i++) {
const gridItem = document.createElement('div');
gridItem.className = 'grid-item';
gridItem.id = `grid-${i}`; // 为每个方块设置唯一ID
// 添加状态指示器
const statusIndicator = document.createElement('div');
statusIndicator.className = 'status-indicator';
gridItem.appendChild(statusIndicator);
// 在方块内部创建4x4小方块
for (let j = 0; j < 16; j++) {
const innerSquare = document.createElement('div');
innerSquare.className = 'inner-square';
gridItem.appendChild(innerSquare);
}
container.appendChild(gridItem);
// 为每个大方块创建独立的WebSocket连接
connectWebSocket(gridItem, i);
}
// WebSocket连接函数
function connectWebSocket(gridItem, index) {
// 替换为实际的WebSocket服务器地址
const wsUrl = `ws://localhost:8080/game/${index}`;
const ws = new WebSocket(wsUrl);
// 获取状态指示器
const statusIndicator = gridItem.querySelector('.status-indicator');
ws.onopen = () => {
console.log(`方块 ${index} 已连接到服务器`);
statusIndicator.classList.add('status-connected');
statusIndicator.classList.remove('status-error');
// 发送初始化消息(示例)
ws.send(JSON.stringify({
type: 'init',
gridId: index
}));
};
ws.onmessage = (event) => {
console.log(`方块 ${index} 收到消息:`, event.data);
// 在此处理服务器消息,更新小方块状态
// 示例:根据消息改变小方块颜色
const data = JSON.parse(event.data);
if (data.type === 'update') {
updateInnerSquares(gridItem, data);
}
};
ws.onerror = (error) => {
console.error(`方块 ${index} 连接错误:`, error);
statusIndicator.classList.remove('status-connected');
statusIndicator.classList.add('status-error');
};
ws.onclose = () => {
console.log(`方块 ${index} 连接关闭`);
statusIndicator.classList.remove('status-connected');
};
// 将WebSocket实例附加到DOM元素上
gridItem.ws = ws;
}
// 更新小方块状态的函数(示例)
function updateInnerSquares(gridItem, data) {
const innerSquares = gridItem.querySelectorAll('.inner-square');
innerSquares.forEach((square, idx) => {
// 根据服务器数据更新小方块样式
// 示例:随机改变背景色
if (data.squares && data.squares[idx]) {
square.style.backgroundColor = data.squares[idx].color;
}
});
}
// 窗口关闭时关闭所有WebSocket连接
window.addEventListener('beforeunload', () => {
document.querySelectorAll('.grid-item').forEach(item => {
if (item.ws && item.ws.readyState === WebSocket.OPEN) {
item.ws.close();
}
});
});
});
</script>
</div>
</body>
</html>

View File

@@ -17,16 +17,16 @@ func init() {
} }
} }
func (m *userManager) Add(cid int32, client *Client) { func (m *userManager) Add(uid int32, client *Client) {
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
m.userMap[cid] = client m.userMap[uid] = client
} }
func (m *userManager) Delete(cid int32) { func (m *userManager) Delete(uid int32) {
m.Lock() m.Lock()
defer m.Unlock() defer m.Unlock()
delete(m.userMap, cid) delete(m.userMap, uid)
} }
func (m *userManager) GetAll() map[int32]*Client { func (m *userManager) GetAll() map[int32]*Client {

View File

@@ -26,8 +26,8 @@ type ISocketServer interface {
// ISocketConn 由网络层实现 // ISocketConn 由网络层实现
type ISocketConn interface { type ISocketConn interface {
GetParam(key string) interface{} GetParam(key string) string
SetParam(key string, values interface{}) SetParam(key string, values string)
Write(data []byte) error Write(data []byte) error
Close() error Close() error
} }

View File

@@ -66,7 +66,7 @@ func (s *WSServer) OnOpen(c gnet.Conn) ([]byte, gnet.Action) {
curHeader: nil, curHeader: nil,
cachedBuf: bytes.Buffer{}, cachedBuf: bytes.Buffer{},
}, },
param: make(map[string]interface{}), param: make(map[string]string),
} }
c.SetContext(ws) c.SetContext(ws)
s.unUpgradeConn.Store(c.RemoteAddr().String(), ws) s.unUpgradeConn.Store(c.RemoteAddr().String(), ws)

View File

@@ -19,7 +19,7 @@ type WSConn struct {
logger logging.Logger logger logging.Logger
isUpgrade bool isUpgrade bool
isClose bool isClose bool
param map[string]interface{} param map[string]string
openTime int64 openTime int64
wsMessageBuf wsMessageBuf
} }
@@ -163,15 +163,17 @@ func (w *WSConn) OnRequest(u []byte) error {
if err != nil { if err != nil {
return err return err
} }
w.SetParam("query", parsedURL.Query()) for key, value := range parsedURL.Query() {
w.SetParam(key, value[0])
}
return nil return nil
} }
func (w *WSConn) GetParam(key string) interface{} { func (w *WSConn) GetParam(key string) string {
return w.param[key] return w.param[key]
} }
func (w *WSConn) SetParam(key string, values interface{}) { func (w *WSConn) SetParam(key string, values string) {
w.param[key] = values w.param[key] = values
} }