winform項目——仿QQ即時通訊程序15:接收驗證消息的反饋

上一篇文章我們完成了驗證消息的接收和存儲,並且在會話列表當中顯示出驗證消息會話。用戶接收到驗證消息以後,是需要對驗證消息進行一個反饋的,在這裡我們只做用戶同意之後的反饋,忽略和拒絕反饋暫時就不做了。那麼本篇文章將實現接收驗證消息的反饋,並且實現互相添加為好友的操作以及在會話列表當中顯示出用戶會話。如下圖所示:

winform項目——仿QQ即時通訊程序15:接收驗證消息的反饋

驗證消息的反饋

首先我們應該分析按了同意按鈕之後要做什麼。

第一步應該是在界面上進行修改,這個操作我們在上一篇文章已經完成了。

第二步應該是對數據進行修改。首先修改的應該是儲存會話列表文件當中的狀態,將該條會話消息的狀態改成1即可表示已經同意了。

緊接著應該對數據庫進行修改,在數據庫的好友表當中,新增兩條記錄,這樣就能夠互相成為好友。具體操作請看同意按鈕的點擊事件中的代碼。

winform項目——仿QQ即時通訊程序15:接收驗證消息的反饋

緊接著我們應該向對方發送一條消息,告訴對方我們已經同意了他的驗證請求,這條消息的格式也需要單獨來設計,這樣客戶端在接收到消息的時候才能夠識別出這是驗證消息的反饋,這個步驟在上一篇文章我們也已經做過。

接著我們還要在雙方客戶端上的會話列表當中生成和對方的會話,同時刷新雙方的好友列表。

我們需要在驗證消息窗體對同意按鈕的點擊事件繼續補充:

private void Agree_btn_MouseClick(object sender, MouseEventArgs e)
{
string account = ((Button)sender).Name.Substring(9);
Control.ControlCollection cc = ((Button)sender).Parent.Controls;
foreach (Control c in cc)
{
if (c is Button)
{
c.Visible = false;
}
if (c is Label)
{
if (c.Name == "state_lbl")
{
c.Text = "已同意";
c.Visible = true;
//修改本地文件中的state
updateFileConfirmState(account, 1);
//修改數據庫好友表,添加兩條記錄,這樣就互相成為好友了
SqlHelper.ExecuteSql("insert into Friends (MyAccount,FriendAccount) values ('"+Common.Account+"','"+account+"')");
SqlHelper.ExecuteSql("insert into Friends (MyAccount,FriendAccount) values ('" + account + "','" + Common.Account + "')");
//發送消息給對方


//第二段內容格式固定,接收時截取出同意,如果是“同意”
//就說明是驗證消息的反饋
Common.sandMsg(account + Common.splitFlag + "~~~" + "同" + "~~~" + "意");
//加載和對方的會話
//在主界面中的會話列表加載和對方的會話
TalkMessage tm = new TalkMessage();
tm.Account = account;
tm.NickName =
Common.majorForm.getNickName(account);
tm.SubMessage = "你已和" + tm.Account + "成為好友"; ;
Common.existedTalk.Add(tm.Account,Common.majorForm.loadtalk(0,tm));

Common.majorForm.refreshTalkList();

Common.majorForm.initFriendList();
}
}
}
}
這些代碼是我經優化過的代碼,在編碼的過程當中,肯定會遇到一些問題,這些都是寶貴的經驗。下面我就說一個特別重要的問題。


點擊同意按鈕之後,本地的客戶端能夠刷新好友列表,但是接收反饋的客戶端並不能刷新會話列表,但是此時查看數據庫好友表當中是有記錄的。客戶端退出重新登陸後也能夠刷新出好友列表,為了解決這個問題,打了好幾個斷點,最終在程序運行的狀態下一直沒有解決掉這個問題。最後我突然想到,要刷新好友列表,必須根據數據庫中的數據來進行刷新,我就使用斷點在讀取數據庫的時候進行檢查,發現點擊同意按鈕之後,對方的客戶端在數據庫當中根本就沒有查詢到好友記錄,但是事實上數據庫當中是有數據記錄的,讀取數據庫的代碼肯定沒有問題,那麼就只有一個原因了,就是因為

延遲的問題。

winform項目——仿QQ即時通訊程序15:接收驗證消息的反饋

點擊同意按鈕之後,我是先發送的驗證消息,然後再對數據庫進行了修改,對方接收到驗證消息之後,立刻在數據庫當中進行讀取,然而此時數據庫根本就沒有執行好插入語句,記錄當然是不存在的。因此我將數據庫操作和發送驗證消息操作調換了一下位置,變成了先改變數據庫,然後發送驗證消息。果然問題就解決掉了。由此可見在編程當中需要考慮到的事情真的是非常多。

修改本地文件中驗證狀態的方法在上一篇文章中已經貼出來了,下面是初始化好友列表的方法:

public void initFriendList()
{
List list = loadFriendList();
loadFriends(list.Count,list);
}

該方法不止在這裡調用,在Major主窗體的load事件中也要調用,記得加上。還有,這個方法是Major窗體中的,通過Common類中定義的Major靜態字段進行調用。

加下來是loadFriends方法:

private void loadFriends(int FriendsNum,List friendsList)
{
//不寫這個會報錯線程間操作控件錯誤
if (this.InvokeRequired)
{
getLoadFriends a = loadFriends;
this.Invoke(a, FriendsNum, friendsList);
return;//一定要記得return或者else啊啊啊!!!!!!
}
rightPanel.Controls.Clear();
for (int i = 0; i < FriendsNum; i++)
{
Panel FriendPanel = new Panel();
FriendPanel.Name = friendsList[i].Account;
FriendPanel.Anchor = ((
System.Windows.Forms.AnchorStyles)(((
System.Windows.Forms.AnchorStyles.Top |
System.Windows.Forms.AnchorStyles.Left)
|
System.Windows.Forms.AnchorStyles.Right)));
FriendPanel.Size = new Size(346, 50);
FriendPanel.Location = new Point(3, i * 50);
FriendPanel.MouseEnter += FriendPanel_MouseEnter;


FriendPanel.MouseLeave += FriendPanel_MouseLeave;

FriendPanel.MouseDoubleClick +=
FriendPanel_MouseDoubleClick;
//頭像
PictureBox pb = new PictureBox();
pb.Size = new Size(30, 30);
pb.Location = new Point(11, 11);
pb.Image = Properties.Resources.知了;
pb.SizeMode =
PictureBoxSizeMode.StretchImage;
pb.MouseEnter += FriendPanel_MouseEnter;
pb.MouseLeave += FriendPanel_MouseLeave;
pb.MouseDoubleClick +=
FriendPanel_MouseDoubleClick;
FriendPanel.Controls.Add(pb);
//暱稱
Label nickname = new Label();
nickname.AutoSize = true;
nickname.Font = new Font("微軟雅黑", 12F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(134)));
nickname.Location = new Point(47, 14);
nickname.Text = friendsList[i].NickName;
nickname.MouseEnter += FriendPanel_MouseEnter;
nickname.MouseLeave += FriendPanel_MouseLeave;
nickname.MouseDoubleClick +=
FriendPanel_MouseDoubleClick;
FriendPanel.Controls.Add(nickname);
//個性簽名
Label signName = new Label();
signName.AutoSize = true;
signName.ForeColor =
SystemColors.ControlDarkDark;
signName.Location = new Point(125, 22);
signName.Size = new Size(277, 15);
signName.Text = friendsList[i].SignName;
signName.MouseEnter += FriendPanel_MouseEnter;
signName.MouseLeave += FriendPanel_MouseLeave;
signName.MouseDoubleClick +=
FriendPanel_MouseDoubleClick;
FriendPanel.Controls.Add(signName);
rightPanel.Controls.Add(FriendPanel);
}
}

該方法在主界面搭建的時候已經貼出一次,這次是進行了一些修改。

Confirm窗體的任務目前為止就已經完成了,現在移步Major主窗體的接收驗證消息的反饋方法這裡。

private void receiveMsg()
{
//死循環保證能一直接收消息
while (true)
{
byte[] buffer = new byte[1024];
int len = Common.socket.Receive(buffer);
//該msg可以是普通消息,也可以是驗證消息
string msg = Encoding.UTF8.GetString(buffer, 0, len);
//通過split將msg中的數據拆分出來
string[] msgarr = msg.Split(new string[] {Common.splitFlag }, StringSplitOptions.None);
//通過判斷拆分後包含幾段來區分是普通消息還是驗證消息
if(msgarr.Length == 3)
{//是普通消息 先不做
MessageBox.Show("1");//測試用
}
else if(msgarr.Length ==2)
{//是驗證消息
//判斷是否是驗證消息的反饋,暫時只識別“同意”反饋
string[] text = msgarr[1].Split(new string[] {"~~~" }, StringSplitOptions.None);
if (text.Length == 3&&text[0] == "" && text[1] == "同"&& text[2]=="意")
{//說明是驗證消息的反饋
//加載和對方的會話
TalkMessage tm = new TalkMessage();
tm.Account = msgarr[0];
tm.SubMessage = "你已和"+tm.Account+"成為好友";
//geiNickName是之前寫好的函數
tm.NickName = getNickName(tm.Account);
//之前寫好的loadtalk方法


//獲取返回值的目的是為了後面判斷該會話是否存在
Panel talkpanel = loadtalk(0,tm);
Common.existedTalk.Add(tm.Account, talkpanel);
//刷新會話列表界面
refreshTalkList();
//初始化好友列表
initFriendList();
}
else
{//普通驗證消息
//1.會話列表出現驗證消息會話
//判斷界面上是否有了驗證消息會話 有就修改,沒有就添加
if (!
Common.existedTalk.ContainsKey("驗證消息"))
{
//不包含就添加到會話列表
TalkMessage tm = new TalkMessage();
tm.NickName = "驗證消息";
tm.SubMessage = msgarr[0] + "請求添加你為好友";
tm.Account = "驗證消息";
Panel talkpanle = loadConfirmTalk(tm);
Common.existedTalk.Add(tm.Account, talkpanle);
//刷新會話列表界面
refreshTalkList();
}
else
{
//已經存在會話列表中了,就修改上面的提示消息
Panel talkpanel = Common.existedTalk["驗證消息"];
foreach (Control c in talkpanel.Controls)
{
if (c is Label)
{
if (((Label)c).Name == "messageName")
{
((Label)c).Text = msgarr[0] + "請求添加你為好友";

}
}
}
//刷新會話列表界面
refreshTalkList();
}
//2.將消息保存到本地文件中,需要保存對方的賬號、暱稱、附加消息和狀態
//為了存取方便,將四種數據存在文本文件的一行,一行就表示一個驗證消息記錄
Thread t = new Thread(saveConfirmMsg);
t.IsBackground = true;
//線程中方法傳參,參數類型必須為object
object m = msgarr;
t.Start(m);
}
}
}
}

這個receiveMsg方法中就包含了接收驗證消息反饋的邏輯,和昨天貼的代碼就一個差別,增加了接收驗證消息反饋的刷新好友列表方法。

好了,到目前為止,接收驗證消息也已經完成了。效果還是不錯的。到這裡,CIM項目其實已經完成的差不多了,只要添加好友能完成,基本上核心內容就做完了一大半。下一篇文章將實現好友間互發消息。


本文系小博客網站原創,轉載請註明文章鏈接地址


分享到:


相關文章: