OpenQQ是可以解决多并发的问题
用OpenQQ实现独占式编辑
服务器端的设计
1、在服务器端项目的全局代码中,加入如下代码:
Public tbrk As new Dictionary(of String,String)
tbrk是一个字典,用于登记每一行是谁在编辑。
我们约定接下来编码的时候:字典的键由表名和行的主键组合成,值则等于编辑者名。
2、在服务端项目的OpenQQ服务端的ReceivedMessage事件加上代码:
Dim msg As String = e.Message
If msg.StartsWith("?#") AndAlso msg.EndsWith("#?") Then '收到请求编辑信号
Dim Key As String = msg.SubString(2,msg.Length - 4)
If tbrk.Containskey(Key) = False Then '如果无人编辑此行
tbrk.Add(Key,e.UserName) '登记申请者为此行的编辑者
e.ReturnValue = "OK" '通知申请者可以编辑
ElseIf tbrk(Key) = e.UserName Then '如果申请者就是之前登记的编辑者
e.ReturnValue = "OK" '通知申请者可以编辑
Else '如果之前登记的编辑者为其他人
e.ReturnValue = tbrk(Key) & "正在编辑此行!" '告知申请者是谁在编辑此行
End If
ElseIf msg.StartsWith("!#") AndAlso msg.EndsWith("#!") Then '收到结束编辑信号
Dim Key As String = msg.SubString(2,msg.Length - 4)
If tbrk.Containskey(Key) Then
tbrk.Remove(Key) '从集合中移除此行的编辑登记
End If
End If
用OpenQQ即时高效同步数据
在多用户协同工作的情况下,如果某用户修改数据后保存,其他用户只有重新加载才能看到最新的数据,参考:数据同步
实际上大多数程序,都是这种被动刷新的方式,例如你在使用网银的时候,只有刷新页面,才能看到刚刚发生的交易;在论坛浏览帖子的时候,只有刷新页面,才能看到他人刚发表的帖子。
也有一些程序,是定时刷新,不管数据有没有变动,到了一定时间,都重新加载数据。
但是上述方式,都没有办法做到即时同步,而且这些方式并非只刷新已经变动的数据,而是重新加载整个页面、甚至整个表,大大增加了服务器的负担,既不即时,也不高效。
有了OpenQQ,我们可以保存某行数据后,通知其他好友,这一行的数据有变化,请重新加载,这样就能做到即时、高效了。
设计步骤:
1、在编辑窗口加一个保存按钮,按钮代码设置为:
Dim r As Row = Tables("表A").Current
Dim p As String = IIF(r.DataRow.RowState = DataRowState.Added, "A#", "U#")
r.Save()
'一定要在保存后合成信息,因为新增行的主键在保存后才生成
Dim msg As String = p & "表A" & "#" & r("_Identify")
For Each bd As QQBuddy In QQClient.Buddies
If bd.Online Then
QQClient.Send(bd.name, msg)
End If
Next
这段代码用于合成通知信息发送给好友,例如"U#表A#8"表A主键为8的行发生了修改,"A#表A#10"表示表A新增了1行,新增行的主键为10。
问题1:用OpenQQ实现独占式编辑与用OpenQQ即时高效同步数据是什么关系?是补充关系,独占式编辑是在编辑,而即时高效同步是在修改或保存?还是二者都是独占式,二者取其一即可?
问题2、在QQClient的ReceivedMessage事件中修改代码:QQClient是在客户端的网络监视器,QQServer是在服务端的网络监视器?QQClient,QQServer是OpenQQ专用语不能改?
问题3:With("?#") AndAlso msg.EndsWith("#?")是字典的键由表名和行的主键组合成,值则等于编辑者名,("?#") 是表名和行的主键的变量,不用写具体的表名,行键名?
"A#", "U#"同("?#")一样都可直接变量
1、没有关系,不同的2个功能
2、对的
3、这些都是一些自己定义的标记,不是什么死规定,只是让接收者知道客户端发过来的信息是干什么的。比如【A#】表示新增数据,你可以已使用自己喜欢的词语,比如【新增行#】,假设新增行的identify值为5,那么客户端就可以发送这样的消息:QQClient.Send(bd.name, "新增行#表A#5"),那么接收者的ReceivedMessage事件接收后就可以判断消息以【新增行#】开头,表示发送者新增保存了一行数据,就可以根据identify值5作为条件追加数据