10分钟教您实现聊天室

这篇教程主要实现了聊天室的登录、登出、群聊、私聊的四个功能,完成效果截图如下:

下面开始按照步骤来实现功能吧!

一、使用VS2010创建对话框程序,并将博维云组件和头文件接入到项目中。

(这里使用到了Json和宽字符之间的转换,所以还需要导入json.cpp和StrWorker.cpp)

云组件接入配置图:

字符处理导入cpp:

二、创建对话框,并实现相关功能。

登录对话框如下:

备注:

Token:处理聊天室数据的云应用对应的登录token,在 云工具的云管理-APP管理-选择app右键功能-选择token管理 进行创建。

昵称:在聊天室里发言的名称,唯一且不重复,在云应用中进行验证。

聊天室对话框如下:

三、在登录对话框中初始化聊天室对话框,并进行登录事件处理(这里只罗列了主要代码:)

初始化在 OnInitDialog() 函数里进行,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
BOOL CChartDemoDlg::OnInitDialog()
{
    CDialogEx::OnInitDialog();

    // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
    //  执行此操作
    SetIcon(m_hIcon, TRUE);         // 设置大图标
    SetIcon(m_hIcon, FALSE);        // 设置小图标

    // TODO: 在此添加额外的初始化代码

    // 初始化client
    CString strTmp = L"";
    BOOL b = m_client.Init();
    if(!b)
    {
        strTmp.Format(L"client初始化失败,ERR: %s",m_client.GetLastErrorW().c_str());
        AfxMessageBox(strTmp);
        exit(0);
    }

    // 注册消息接收窗口
    m_client.RegRecvCWnd(WM_USER_MSG_RECEIVE,this);

    // 创建聊天窗口
    m_chartDlg.Create(IDD_DIALOG_CHART,this);
    m_chartDlg.SetParent(this);

    return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

登录事件处理代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// 登录事件
void CChartDemoDlg::OnBnClickedLogin()
{
    CString strToken = L"",strName = L"",strTmp = L"";
   
    m_editToken.GetWindowText(strToken);
    m_editName.GetWindowText(strName);

    // check
    if(strToken.GetLength() == 0)
    {
        AfxMessageBox(L"token不能为空!");
        return;
    }
    if(strName.GetLength() == 0)
    {
        AfxMessageBox(L"昵称不能为空!");
        return;
    }

    // login
    std::wstring out_res = L"";
    BOOL b = m_client.LoginW(strToken,strName,&out_res);
    if(!b)
    {
        std::wstring strErr = (out_res.length() != 0 ? out_res : m_client.GetLastErrorW());
        strTmp.Format(L"登录失败,ERR: %s",strErr.c_str());
        AfxMessageBox(strTmp);
        return;
    }

    m_myName = strName;

    // 开启聊天界面
    // 移到正中
    CRect rect,rcChart;
    GetWindowRect(&rect);
    m_chartDlg.GetWindowRect(&rcChart);
    int nWidth = rcChart.Width();
    int nHeight = rcChart.Height();
    rcChart.left = rect.left + rect.Width() / 2 - nWidth / 2;
    rcChart.top = rect.top + rect.Height() / 2 - nHeight / 2;
    rcChart.right = rcChart.left + nWidth;
    rcChart.bottom = rcChart.top + nHeight;
    m_chartDlg.MoveWindow(&rcChart);

    m_chartDlg.ShowWindow(SW_SHOW);

    // 刷新成员列表
    m_chartDlg.UpdateNameList();

    // 隐藏登录窗口
    rect.top = rect.bottom = 0;
    MoveWindow(&rect);
}

聊天室发送消息代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
// 发送消息
void CChartDlg::OnBnClickedButtonSend()
{
    // 1 判断是私聊还是群聊
    CString strToName = L"",strTmp = L"";
    BOOL bToAll = TRUE;
    if(m_radioPeople.GetCheck())
        bToAll = FALSE;
    if(!bToAll)
    {
        // 私聊获取选择的昵称
        int nSel = m_listName.GetCurSel();
        m_listName.GetText(nSel,strToName);

        if(strToName.GetLength() == 0)
        {
            AfxMessageBox(L"私聊必须选择成员!");
            return;
        }
    }

    // 2 获取发送消息
    CString strTalk = L"";
    m_editTalk.GetWindowText(strTalk);
    if(strTalk.GetLength() == 0)
    {
        AfxMessageBox(L"发送消息不能为空!");
        return;
    }

    // 2 组合消息
    Json::Value root;
    Json::FastWriter w;
    root["from_name"] = CStrWorker::WcharToString(((CChartDemoDlg*)m_pParent)->m_myName);
    root["talk"] = CStrWorker::WcharToString(strTalk);
    if(!bToAll)
    {
        root["type"] = "to people";
        root["to_name"] = CStrWorker::WcharToString(strToName);
    }
    else
    {
        root["type"] = "to all";
    }

    // 3 将消息请求发到ser
    std::string out_res = "";
    std::string strSend = w.write(root);
    BOOL b = ((CChartDemoDlg*)m_pParent)->m_client.Request(strSend.c_str(),&out_res);
    if(!b)
    {
        strTmp.Format(L"发送消息失败,ERR: %s",((CChartDemoDlg*)m_pParent)->m_client.GetLastErrorW().c_str());
        AfxMessageBox(strTmp);
        return;
    }

    // 清空消息框
    m_editTalk.SetWindowText(L"");
}

人员退出聊天室代码:

1
2
3
4
5
6
7
void CChartDlg::OnClose()
{
    CDialogEx::OnClose();
    // 通知ser人员退出
    ((CChartDemoDlg*)m_pParent)->m_client.LogoutW(L"exit");
    exit(0);
}

四、云端数据处理代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
array<string> m_arrName; // 保存聊天人员的昵称

// 程序入口函数
void _main()
{
    // 这里开始脚本逻辑
    Print("Hello World!");

}

// 客户端登录事件
bool _login(string&in from, string&out msg)
{
    Print("login from:"+from);
    // 1 得到登录聊天室的昵称
    Json json(from);
    string token = json.getString("token");
    string name = json.getString("custom_code");

    // 2 检查昵称是否重复
    bool bExists = false;
    for(uint i=0;i<m_arrName.size();i++)
    {
        string tmp_name = m_arrName[i];
        if(tmp_name == name)
        {
            bExists = true;
            break;
        }
    }

    if(bExists)
    {
        msg = "昵称已被使用";
        return false;
    }

    // 保存新的昵称数据
    m_arrName.push_back(name);

    // 通知所有人有新成员
    Json tmp;
    tmp.putString("type","add");
    tmp.putString("name",name);
    int count = PushToAll(tmp.toString());
    Print("push, count:"+count);

    return true;
}

// 客户端登出事件
void _logout(string&in from, string&in msg)
{
    Print("logout from:"+from);
    // 1 得到登录聊天室的昵称
    Json json(from);
    string token = json.getString("token");
    string name = json.getString("custom_code");
   
    // 2 删除昵称数据
    int index = m_arrName.find(name);
    if(index != -1)
        m_arrName.erase(index);

    // 3 给所有人推送退出消息
    Json tmp;
    tmp.putString("type","exit");
    tmp.putString("name",name);
    int count = PushToAll(tmp.toString());
    Print("push, count:"+count);
}

// 客户端短连接消息事件
string _request(string&in from, string&in msg)
{
    // 1 得到发送消息的昵称
    Json json(from);
    string token = json.getString("token");
    string name = json.getString("custom_code");

    // 2 判断是否为群聊还是私聊
    Json jsMsg(msg);
    string type = jsMsg.getString("type");

    // 3 拼接要推送的消息内容并推送
    if(type == "get list")
    {
        // 组合信息
        JsonArray root;
        for(uint i=0;i<m_arrName.size();i++)
        {
            string tmp_name = m_arrName[i];
            Json tmp;
            tmp.putString("name",tmp_name);
            root.put(tmp);
        }
        return root.toString();
    }
    else if(type == "to all")
    {
        PushToAll(msg);
    }
    else if(type == "to people")
    {
        Json tmp(msg);
        string to_name = tmp.getString("to_name");
        PushToCustomCode(to_name,msg);
    }

    return "ok";
}

=============下载聊天室Demo=============

发表评论

电子邮件地址不会被公开。 必填项已用*标注