体育赛事直播系统开发:实现用户群聊和发红包功能的关键部分代码

简介: 本方案基于体育赛事直播系统的聊一聊功能模块,实现群聊与发红包的核心功能。技术栈包括后端PHP-ThinkPHP、安卓-Java、iOS-OC及PC/H5-Vue.js。数据库采用MySQL设计,包含群组、成员、消息、红包及其领取记录表。后端提供创建群组、发送消息和红包、领取红包等API接口;前端Vue.js实现群聊界面与WebSocket实时消息推送;移动端(Android/iOS)通过WebSocket接收消息并展示。整体架构支持多平台交互,确保实时性与用户体验。

基于“东莞梦幻网络科技”体育赛事直播系统中的聊一聊功能模块的群聊和发红包关键代码实现方案,所用技术栈(后端:PHP-ThinkPHP、安卓-Java、iOS-OC、PC/H5-Vue.js)。

数据库表设计(MySQL)

-- 群组表
CREATE TABLE `groups` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `creator_id` int(11) NOT NULL,
  `avatar` varchar(255) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`)
);

-- 群成员表
CREATE TABLE `group_members` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `group_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `role` tinyint(1) DEFAULT '0' COMMENT '0-普通成员 1-管理员 2-群主',
  `joined_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `group_user` (`group_id`,`user_id`)
);

-- 消息表
CREATE TABLE `messages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `group_id` int(11) NOT NULL,
  `sender_id` int(11) NOT NULL,
  `content` text NOT NULL,
  `type` tinyint(1) DEFAULT '0' COMMENT '0-文本 1-图片 2-红包 3-系统通知',
  `created_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `group_id` (`group_id`)
);

-- 红包表
CREATE TABLE `red_packets` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `group_id` int(11) NOT NULL,
  `sender_id` int(11) NOT NULL,
  `amount` decimal(10,2) NOT NULL,
  `count` int(11) NOT NULL,
  `remain_amount` decimal(10,2) NOT NULL,
  `remain_count` int(11) NOT NULL,
  `message` varchar(255) DEFAULT NULL,
  `created_at` datetime NOT NULL,
  `expire_at` datetime NOT NULL,
  `status` tinyint(1) DEFAULT '0' COMMENT '0-未领完 1-已领完 2-已过期',
  PRIMARY KEY (`id`)
);

-- 红包领取记录
CREATE TABLE `red_packet_records` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `red_packet_id` int(11) NOT NULL,
  `receiver_id` int(11) NOT NULL,
  `amount` decimal(10,2) NOT NULL,
  `received_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  KEY `red_packet_id` (`red_packet_id`)
);

后端实现 (ThinkPHP)

群聊API控制器

<?php
namespace app\api\controller;

use think\Controller;
use think\Request;

class Group extends Controller
{
   
    // 创建群组
    public function create()
    {
   
        $user_id = Request::instance()->param('user_id');
        $name = Request::instance()->param('name');

        $group_id = Db::name('groups')->insertGetId([
            'name' => $name,
            'creator_id' => $user_id,
            'created_at' => date('Y-m-d H:i:s'),
            'updated_at' => date('Y-m-d H:i:s')
        ]);

        // 添加创建者为群主
        Db::name('group_members')->insert([
            'group_id' => $group_id,
            'user_id' => $user_id,
            'role' => 2, // 群主
            'joined_at' => date('Y-m-d H:i:s')
        ]);

        return json(['code' => 0, 'data' => ['group_id' => $group_id]]);
    }

    // 发送群消息
    public function sendMessage()
    {
   
        $group_id = Request::instance()->param('group_id');
        $user_id = Request::instance()->param('user_id');
        $content = Request::instance()->param('content');

        // 检查是否是群成员
        $is_member = Db::name('group_members')
            ->where('group_id', $group_id)
            ->where('user_id', $user_id)
            ->count();

        if(!$is_member) {
   
            return json(['code' => 1, 'msg' => '您不是该群成员']);
        }

        // 保存消息到数据库
        $message_id = Db::name('messages')->insertGetId([
            'group_id' => $group_id,
            'sender_id' => $user_id,
            'content' => $content,
            'type' => 0,
            'created_at' => date('Y-m-d H:i:s')
        ]);

        // 通过WebSocket推送消息
        // 实际实现中应该调用WebSocket服务推送

        return json(['code' => 0, 'data' => ['message_id' => $message_id]]);
    }

    // 发送红包
    public function sendRedPacket()
    {
   
        $group_id = Request::instance()->param('group_id');
        $user_id = Request::instance()->param('user_id');
        $amount = Request::instance()->param('amount');
        $count = Request::instance()->param('count');
        $message = Request::instance()->param('message', '');

        // 检查余额等逻辑

        // 创建红包
        $red_packet_id = Db::name('red_packets')->insertGetId([
            'group_id' => $group_id,
            'sender_id' => $user_id,
            'amount' => $amount,
            'count' => $count,
            'remain_amount' => $amount,
            'remain_count' => $count,
            'message' => $message,
            'created_at' => date('Y-m-d H:i:s'),
            'expire_at' => date('Y-m-d H:i:s', time() + 86400), // 24小时后过期
            'status' => 0
        ]);

        // 保存消息
        $message_id = Db::name('messages')->insertGetId([
            'group_id' => $group_id,
            'sender_id' => $user_id,
            'content' => json_encode(['red_packet_id' => $red_packet_id]),
            'type' => 2, // 红包消息
            'created_at' => date('Y-m-d H:i:s')
        ]);

        return json(['code' => 0, 'data' => ['red_packet_id' => $red_packet_id]]);
    }

    // 领取红包
    public function receiveRedPacket()
    {
   
        $red_packet_id = Request::instance()->param('red_packet_id');
        $user_id = Request::instance()->param('user_id');

        // 检查红包状态
        $red_packet = Db::name('red_packets')->find($red_packet_id);
        if(!$red_packet || $red_packet['status'] != 0) {
   
            return json(['code' => 1, 'msg' => '红包已领取完或已过期']);
        }

        // 检查是否已领取
        $has_received = Db::name('red_packet_records')
            ->where('red_packet_id', $red_packet_id)
            ->where('receiver_id', $user_id)
            ->count();

        if($has_received) {
   
            return json(['code' => 2, 'msg' => '您已领取过该红包']);
        }

        // 计算领取金额
        $amount = $this->calculateRedPacketAmount($red_packet);

        // 更新红包状态
        Db::name('red_packets')
            ->where('id', $red_packet_id)
            ->update([
                'remain_amount' => Db::raw('remain_amount-' . $amount),
                'remain_count' => Db::raw('remain_count-1'),
                'status' => $red_packet['remain_count'] == 1 ? 1 : 0
            ]);

        // 添加领取记录
        Db::name('red_packet_records')->insert([
            'red_packet_id' => $red_packet_id,
            'receiver_id' => $user_id,
            'amount' => $amount,
            'received_at' => date('Y-m-d H:i:s')
        ]);

        // 更新用户余额等逻辑

        return json(['code' => 0, 'data' => ['amount' => $amount]]);
    }

    private function calculateRedPacketAmount($red_packet)
    {
   
        // 简单实现:平均分配
        if($red_packet['remain_count'] == 1) {
   
            return $red_packet['remain_amount'];
        }

        $avg = $red_packet['remain_amount'] / $red_packet['remain_count'];
        $min = 0.01;
        $max = $avg * 2;
        $amount = mt_rand($min * 100, $max * 100) / 100;
        $amount = min($amount, $red_packet['remain_amount'] - ($red_packet['remain_count'] - 1) * 0.01);

        return round($amount, 2);
    }
}

前端实现 (Vue.js)

群聊主界面组件

<template>
  <div class="group-chat-container">
    <!-- 群聊头部 -->
    <div class="chat-header">
      <h2>{
  { groupName }}</h2>
      <div class="header-actions">
        <button @click="showGroupInfo">群信息</button>
        <button @click="showRedPacketDialog">发红包</button>
      </div>
    </div>

    <!-- 消息列表 -->
    <div class="message-list" ref="messageList">
      <div v-for="(message, index) in messages" :key="index" 
           :class="['message-item', message.sender_id === currentUserId ? 'self' : 'other']">
        <div v-if="message.type === 0" class="text-message">
          <div class="sender-name" v-if="message.sender_id !== currentUserId">
            {
  { getMemberName(message.sender_id) }}
          </div>
          <div class="message-content">{
  { message.content }}</div>
          <div class="message-time">{
  { formatTime(message.created_at) }}</div>
        </div>

        <div v-else-if="message.type === 2" class="red-packet-message">
          <div class="sender-name">{
  { getMemberName(message.sender_id) }}的红包</div>
          <div class="red-packet-content" @click="openRedPacket(message)">
            <div class="red-packet-icon">🧧</div>
            <div class="red-packet-message-text">{
  { getRedPacketMessage(message) }}</div>
          </div>
          <div class="message-time">{
  { formatTime(message.created_at) }}</div>
        </div>
      </div>
    </div>

    <!-- 输入框 -->
    <div class="message-input">
      <input v-model="inputMessage" @keyup.enter="sendMessage" placeholder="输入消息...">
      <button @click="sendMessage">发送</button>
    </div>

    <!-- 红包对话框 -->
    <div v-if="showRedPacket" class="red-packet-dialog">
      <div class="red-packet-box">
        <h3>发红包</h3>
        <div class="red-packet-form">
          <div class="form-item">
            <label>金额</label>
            <input type="number" v-model="redPacketAmount" placeholder="输入金额">
          </div>
          <div class="form-item">
            <label>个数</label>
            <input type="number" v-model="redPacketCount" placeholder="输入红包个数">
          </div>
          <div class="form-item">
            <label>留言</label>
            <input v-model="redPacketMessage" placeholder="恭喜发财">
          </div>
          <div class="form-actions">
            <button @click="sendRedPacket">塞钱进红包</button>
            <button @click="showRedPacket = false">取消</button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
    
  data() {
    
    return {
    
      groupId: null,
      groupName: '群聊名称',
      currentUserId: 1, // 当前用户ID
      messages: [],
      inputMessage: '',
      showRedPacket: false,
      redPacketAmount: '',
      redPacketCount: 1,
      redPacketMessage: '恭喜发财',
      members: [],
      ws: null
    }
  },

  mounted() {
    
    this.groupId = this.$route.params.groupId;
    this.loadGroupInfo();
    this.loadMessages();
    this.connectWebSocket();
  },

  methods: {
    
    async loadGroupInfo() {
    
      try {
    
        const response = await this.$http.get(`/api/group/info/${
      this.groupId}`);
        this.groupName = response.data.name;
        this.members = response.data.members;
      } catch (error) {
    
        console.error('获取群信息失败:', error);
      }
    },

    async loadMessages() {
    
      try {
    
        const response = await this.$http.get(`/api/group/messages/${
      this.groupId}`);
        this.messages = response.data;
        this.$nextTick(() => {
    
          this.scrollToBottom();
        });
      } catch (error) {
    
        console.error('获取消息失败:', error);
      }
    },

    connectWebSocket() {
    
      this.ws = new WebSocket(`ws://your-websocket-server:2346?user_id=${
      this.currentUserId}`);

      this.ws.onmessage = (event) => {
    
        const message = JSON.parse(event.data);
        if(message.group_id === this.groupId) {
    
          this.messages.push(message);
          this.$nextTick(() => {
    
            this.scrollToBottom();
          });
        }
      };

      this.ws.onclose = () => {
    
        console.log('WebSocket连接关闭');
      };
    },

    sendMessage() {
    
      if(!this.inputMessage.trim()) return;

      const message = {
    
        type: 'group_message',
        group_id: this.groupId,
        sender_id: this.currentUserId,
        content: this.inputMessage
      };

      this.ws.send(JSON.stringify(message));

      // 添加到本地消息列表
      this.messages.push({
    
        group_id: this.groupId,
        sender_id: this.currentUserId,
        content: this.inputMessage,
        type: 0,
        created_at: new Date().toISOString()
      });

      this.inputMessage = '';
      this.$nextTick(() => {
    
        this.scrollToBottom();
      });
    },

    scrollToBottom() {
    
      const container = this.$refs.messageList;
      container.scrollTop = container.scrollHeight;
    },

    showRedPacketDialog() {
    
      this.showRedPacket = true;
    },

    async sendRedPacket() {
    
      try {
    
        const response = await this.$http.post('/api/group/sendRedPacket', {
    
          group_id: this.groupId,
          user_id: this.currentUserId,
          amount: this.redPacketAmount,
          count: this.redPacketCount,
          message: this.redPacketMessage
        });

        // 添加到消息列表
        this.messages.push({
    
          group_id: this.groupId,
          sender_id: this.currentUserId,
          content: JSON.stringify({
    red_packet_id: response.data.red_packet_id}),
          type: 2,
          created_at: new Date().toISOString()
        });

        this.showRedPacket = false;
        this.redPacketAmount = '';
        this.redPacketCount = 1;
        this.redPacketMessage = '恭喜发财';

        this.$nextTick(() => {
    
          this.scrollToBottom();
        });
      } catch (error) {
    
        console.error('发送红包失败:', error);
      }
    },

    async openRedPacket(message) {
    
      try {
    
        const content = JSON.parse(message.content);
        const response = await this.$http.post('/api/group/receiveRedPacket', {
    
          red_packet_id: content.red_packet_id,
          user_id: this.currentUserId
        });

        alert(`恭喜您领取了${
      response.data.amount}元红包`);
      } catch (error) {
    
        console.error('领取红包失败:', error);
        alert(error.response?.data?.msg || '领取红包失败');
      }
    },

    getMemberName(userId) {
    
      const member = this.members.find(m => m.user_id === userId);
      return member ? member.name : '未知用户';
    },

    getRedPacketMessage(message) {
    
      try {
    
        const content = JSON.parse(message.content);
        return content.message || '恭喜发财';
      } catch {
    
        return '恭喜发财';
      }
    },

    formatTime(time) {
    
      return new Date(time).toLocaleTimeString([], {
    hour: '2-digit', minute:'2-digit'});
    },

    showGroupInfo() {
    
      // 显示群信息
    }
  },

  beforeDestroy() {
    
    if(this.ws) {
    
      this.ws.close();
    }
  }
}
</script>

<style scoped>
.group-chat-container {
    
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.chat-header {
    
  padding: 10px;
  background: #f5f5f5;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.message-list {
    
  flex: 1;
  overflow-y: auto;
  padding: 10px;
}

.message-item {
    
  margin-bottom: 15px;
}

.message-item.self {
    
  text-align: right;
}

.message-item.other {
    
  text-align: left;
}

.sender-name {
    
  font-size: 12px;
  color: #666;
  margin-bottom: 5px;
}

.message-content {
    
  display: inline-block;
  padding: 8px 12px;
  background: #e6f7ff;
  border-radius: 4px;
  max-width: 70%;
  word-break: break-word;
}

.message-item.self .message-content {
    
  background: #69c0ff;
  color: white;
}

.message-time {
    
  font-size: 10px;
  color: #999;
  margin-top: 3px;
}

.message-input {
    
  padding: 10px;
  display: flex;
  border-top: 1px solid #eee;
}

.message-input input {
    
  flex: 1;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
  margin-right: 10px;
}

.red-packet-message {
    
  cursor: pointer;
}

.red-packet-content {
    
  display: inline-flex;
  align-items: center;
  padding: 8px 12px;
  background: #ff4d4f;
  color: white;
  border-radius: 4px;
}

.red-packet-icon {
    
  font-size: 20px;
  margin-right: 8px;
}

.red-packet-dialog {
    
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.red-packet-box {
    
  background: white;
  padding: 20px;
  border-radius: 8px;
  width: 300px;
}

.red-packet-form .form-item {
    
  margin-bottom: 15px;
}

.red-packet-form label {
    
  display: block;
  margin-bottom: 5px;
  font-weight: bold;
}

.red-packet-form input {
    
  width: 100%;
  padding: 8px;
  border: 1px solid #ddd;
  border-radius: 4px;
}

.form-actions {
    
  display: flex;
  justify-content: space-between;
  margin-top: 20px;
}

.form-actions button {
    
  padding: 8px 15px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.form-actions button:first-child {
    
  background: #ff4d4f;
  color: white;
}

.form-actions button:last-child {
    
  background: #f5f5f5;
}
</style>

Android实现 (Java)

public class GroupChatActivity extends AppCompatActivity implements ChatWebSocketClient.ChatMessageListener {
   
    private static final String WS_URL = "ws://your-websocket-server:2346";

    private RecyclerView messageRecyclerView;
    private EditText messageInput;
    private Button sendButton;
    private ChatWebSocketClient webSocketClient;
    private MessageAdapter messageAdapter;
    private List<ChatMessage> messages = new ArrayList<>();
    private int currentUserId = 1; // 当前用户ID
    private int groupId;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
   
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_group_chat);

        groupId = getIntent().getIntExtra("group_id", 0);

        messageRecyclerView = findViewById(R.id.message_recycler_view);
        messageInput = findViewById(R.id.message_input);
        sendButton = findViewById(R.id.send_button);

        // 设置RecyclerView
        messageAdapter = new MessageAdapter(messages, currentUserId);
        messageRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        messageRecyclerView.setAdapter(messageAdapter);

        // 连接WebSocket
        try {
   
            webSocketClient = new ChatWebSocketClient(new URI(WS_URL + "?user_id=" + currentUserId), this);
            webSocketClient.connect();
        } catch (URISyntaxException e) {
   
            e.printStackTrace();
        }

        // 发送消息
        sendButton.setOnClickListener(v -> sendMessage());

        // 加载历史消息
        loadMessages();
    }

    private void sendMessage() {
   
        String content = messageInput.getText().toString().trim();
        if (content.isEmpty()) return;

        try {
   
            JSONObject message = new JSONObject();
            message.put("type", "group_message");
            message.put("group_id", groupId);
            message.put("sender_id", currentUserId);
            message.put("content", content);

            if (webSocketClient != null && webSocketClient.isOpen()) {
   
                webSocketClient.send(message.toString());

                // 添加到本地列表
                ChatMessage chatMessage = new ChatMessage();
                chatMessage.setGroupId(groupId);
                chatMessage.setSenderId(currentUserId);
                chatMessage.setContent(content);
                chatMessage.setType(0); // 文本消息
                chatMessage.setTime(new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date()));

                messages.add(chatMessage);
                messageAdapter.notifyItemInserted(messages.size() - 1);
                messageRecyclerView.scrollToPosition(messages.size() - 1);

                messageInput.setText("");
            }
        } catch (JSONException e) {
   
            e.printStackTrace();
        }
    }

    private void loadMessages() {
   
        // 从API加载历史消息
        // 实现网络请求获取消息列表
    }

    @Override
    public void onGroupMessageReceived(int groupId, int senderId, String content, String time) {
   
        if (this.groupId == groupId) {
   
            runOnUiThread(() -> {
   
                ChatMessage message = new ChatMessage();
                message.setGroupId(groupId);
                message.setSenderId(senderId);
                message.setContent(content);
                message.setType(0); // 文本消息
                message.setTime(time);

                messages.add(message);
                messageAdapter.notifyItemInserted(messages.size() - 1);
                messageRecyclerView.scrollToPosition(messages.size() - 1);
            });
        }
    }

    @Override
    public void onRedPacketReceived(int groupId, int senderId, int redPacketId, String message) {
   
        // 处理红包消息
    }

    @Override
    protected void onDestroy() {
   
        super.onDestroy();
        if (webSocketClient != null) {
   
            webSocketClient.close();
        }
    }
}

class MessageAdapter extends RecyclerView.Adapter<MessageAdapter.MessageViewHolder> {
   
    private List<ChatMessage> messages;
    private int currentUserId;

    public MessageAdapter(List<ChatMessage> messages, int currentUserId) {
   
        this.messages = messages;
        this.currentUserId = currentUserId;
    }

    @Override
    public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
   
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.item_message, parent, false);
        return new MessageViewHolder(view);
    }

    @Override
    public void onBindViewHolder(MessageViewHolder holder, int position) {
   
        ChatMessage message = messages.get(position);

        if (message.getSenderId() == currentUserId) {
   
            // 自己的消息
            holder.messageLayout.setGravity(Gravity.END);
            holder.messageContent.setBackgroundResource(R.drawable.bg_message_self);
        } else {
   
            // 别人的消息
            holder.messageLayout.setGravity(Gravity.START);
            holder.messageContent.setBackgroundResource(R.drawable.bg_message_other);
            holder.senderName.setText("用户" + message.getSenderId());
            holder.senderName.setVisibility(View.VISIBLE);
        }

        holder.messageContent.setText(message.getContent());
        holder.messageTime.setText(message.getTime());
    }

    @Override
    public int getItemCount() {
   
        return messages.size();
    }

    class MessageViewHolder extends RecyclerView.ViewHolder {
   
        LinearLayout messageLayout;
        TextView senderName;
        TextView messageContent;
        TextView messageTime;

        public MessageViewHolder(View itemView) {
   
            super(itemView);
            messageLayout = itemView.findViewById(R.id.message_layout);
            senderName = itemView.findViewById(R.id.sender_name);
            messageContent = itemView.findViewById(R.id.message_content);
            messageTime = itemView.findViewById(R.id.message_time);
        }
    }
}

iOS实现 (Objective-C)

#import "ChatWebSocketClient.h"
#import "SRWebSocket.h"

@interface ChatWebSocketClient () <SRWebSocketDelegate>
@property (nonatomic, strong) SRWebSocket *webSocket;
@property (nonatomic, weak) id<ChatMessageDelegate> delegate;
@end

@implementation ChatWebSocketClient

- (instancetype)initWithURL:(NSURL *)url delegate:(id<ChatMessageDelegate>)delegate {
   
    self = [super init];
    if (self) {
   
        _delegate = delegate;
        _webSocket = [[SRWebSocket alloc] initWithURL:url];
        _webSocket.delegate = self;
        [_webSocket open];
    }
    return self;
}

- (void)sendMessage:(NSDictionary *)message {
   
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:message options:0 error:&error];
    if (!error) {
   
        NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        [_webSocket send:jsonString];
    }
}

- (void)close {
   
    [_webSocket close];
}

#pragma mark - SRWebSocketDelegate

- (void)webSocketDidOpen:(SRWebSocket *)webSocket {
   
    NSLog(@"WebSocket连接已打开");
}

- (void)webSocket:(SRWebSocket *)webSocket didReceiveMessage:(id)message {
   
    NSLog(@"收到消息: %@", message);

    if ([message isKindOfClass:[NSString class]]) {
   
        NSError *error;
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:[message dataUsingEncoding:NSUTF8StringEncoding] 
                                                           options:0 
                                                             error:&error];
        if (!error) {
   
            NSString *type = json[@"type"];
            if ([type isEqualToString:@"group_message"]) {
   
                NSInteger groupId = [json[@"group_id"] integerValue];
                NSInteger senderId = [json[@"sender_id"] integerValue];
                NSString *content = json[@"content"];
                NSString *time = json[@"time"];

                if ([self.delegate respondsToSelector:@selector(didReceiveGroupMessage:groupId:senderId:content:time:)]) {
   
                    [self.delegate didReceiveGroupMessage:self groupId:groupId senderId:senderId content:content time:time];
                }
            } else if ([type isEqualToString:@"red_packet"]) {
   
                // 处理红包消息
            }
        }
    }
}

- (void)webSocket:(SRWebSocket *)webSocket didFailWithError:(NSError *)error {
   
    NSLog(@"WebSocket错误: %@", error);
}

- (void)webSocket:(SRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean {
   
    NSLog(@"WebSocket连接已关闭: %@", reason);
}

@end

群聊-详情-群主.png
群聊已抢到红包.png

相关文章
|
11月前
|
安全 Java 数据库连接
一把锁的两种承诺:synchronized如何同时保证互斥与内存可见性?
临界区指多线程中访问共享资源的代码段,需通过互斥机制防止数据不一致与竞态条件。Java用`synchronized`实现同步,保证同一时刻仅一个线程执行临界区代码,并借助happens-before规则确保内存可见性与操作顺序,从而保障线程安全。
404 11
|
数据采集 存储 Web App开发
Python爬虫技巧:设置Cookie永不超时的详细指南
Python爬虫技巧:设置Cookie永不超时的详细指南
|
关系型数据库 决策智能
RT-DETR改进策略【损失函数篇】| Slide Loss,解决简单样本和困难样本之间的不平衡问题
RT-DETR改进策略【损失函数篇】| Slide Loss,解决简单样本和困难样本之间的不平衡问题
779 3
RT-DETR改进策略【损失函数篇】| Slide Loss,解决简单样本和困难样本之间的不平衡问题
|
测试技术 API 微服务
性能测试并发量评估新思考
性能测试并发量评估新思考
927 20
性能测试并发量评估新思考
|
开发工具 Android开发
Android Studio resource linking failed
Android Studio resource linking failed
681 1
|
机器学习/深度学习 人工智能 自然语言处理
前端大模型入门(三):编码(Tokenizer)和嵌入(Embedding)解析 - llm的输入
本文介绍了大规模语言模型(LLM)中的两个核心概念:Tokenizer和Embedding。Tokenizer将文本转换为模型可处理的数字ID,而Embedding则将这些ID转化为能捕捉语义关系的稠密向量。文章通过具体示例和代码展示了两者的实现方法,帮助读者理解其基本原理和应用场景。
6111 1
|
存储 数据管理 Linux
Linux - 记录问题:docker 迁移 更改镜像默认位置的注意事项
Linux - 记录问题:docker 迁移 更改镜像默认位置的注意事项
787 0
|
Rust 算法 编译器
用Numba:一行代码将Python程序运行速度提升100倍
Numba是一款可以将python函数编译为机器代码的JIT编译器,由Anaconda公司主导开发,可以对Python原生代码进行CPU和GPU加速。Numba非常擅长加速数值运算,他对Numpy支持得非常好,Numpy经过Numba加速后的速度接近C和Fortran。
2112 0
用Numba:一行代码将Python程序运行速度提升100倍
|
Linux 芯片 Windows
嵌入式Linux系列第3篇:uboot编译下载
嵌入式Linux系列第3篇:uboot编译下载
|
存储 缓存 监控
Linux 文件系统全面解析:从基本原理到实际应用
Linux 文件系统全面解析:从基本原理到实际应用
1699 0