本文以网页端实现即时通信,用抢麦器的业务场景来完成即时的效果,需要Fleck.dll和Newtonsoft.Json.dll支持,Fleck是即时通信的核心,Newtonsoft.Json是json格式数据交互解析时用到的,均已上传到我的资源中,也可以在其他地方下载 1.后端socket服务实现 以控制台的方式简单实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Fleck;
using Newtonsoft.Json;
using System.Threading;
namespace WebSocketTest
{
class Program
{
private static List<IWebSocketConnection> allSockets = new List<IWebSocketConnection>();
private static WebSocketServer server = new WebSocketServer("ws://0.0.0.0:7181");
private static List<string> currentMic = new List<string>();
private static int timeDown= 15;
static void Main(string[] args)
{
FleckLog.Level = LogLevel.Debug;
Thread timeControl = new Thread(() => {
while (true) {
if (timeDown == 0)
{
currentMic.RemoveAt(0);
timeDown = 15;
MsgClass mc = new MsgClass();
mc.op = "systemdownmic";
mc.id = "";
Console.WriteLine("server:" + JsonConvert.SerializeObject(mc));
allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(mc)));
}
if (currentMic.Count == 0)
{
System.Threading.Thread.CurrentThread.Suspend();
}
System.Threading.Thread.Sleep(1000);
timeDown--;
}
});
server.Start(socket =>{
socket.OnOpen = () =>
{
Console.WriteLine("Open!");
allSockets.Add(socket);
if (currentMic.Count > 0)
{
MsgClass mc = new MsgClass();
mc.op = "init";
mc.currMic = currentMic;
mc.id = timeDown.ToString();
Console.WriteLine("server:" + JsonConvert.SerializeObject(mc));
socket.Send(JsonConvert.SerializeObject(mc));
}
};
socket.OnClose = () =>
{
Console.WriteLine("Close!");
allSockets.Remove(socket);
};
socket.OnMessage = message =>
{
Console.WriteLine("client:"+message);
MsgClass messageObj =JsonConvert.DeserializeObject<MsgClass>(message);
if (messageObj.op == "upmic")
{
if (currentMic.Count == 0)
{
timeDown = 15;
if (timeControl.ThreadState == ThreadState.Suspended)
{
timeControl.Resume();
}
else
{
timeControl.Start();
}
}
if (currentMic.Contains(messageObj.id))
{
return;
}
currentMic.Add(messageObj.id);
}
else if (messageObj.op == "downmic")
{
bool isfisrt = false;
if (currentMic.IndexOf(messageObj.id) == 0)
{
isfisrt = true;
}
currentMic.Remove(messageObj.id);
if (currentMic.Count == 0)
{
if (timeControl.ThreadState == ThreadState.Running)
{
timeDown = 15;
timeControl.Suspend();
}
}
else if (isfisrt && currentMic.Count > 0)
{
timeControl.Suspend();
timeDown = 15;
timeControl.Resume();
}
}
else if (messageObj.op == "alldownmic")
{
currentMic.Clear();
timeDown = 15;
timeControl.Suspend();
}
else if (messageObj.op == "addtime")
{
timeDown += 15;
}
else if (messageObj.op == "controlmic")
{
if (messageObj.id == "")
{
return;
}
if (currentMic[0] == messageObj.id && currentMic.Count == 1)
{
timeControl.Suspend();
timeDown = 15;
}
else if (currentMic[0] == messageObj.id && currentMic.Count > 1)
{
timeControl.Suspend();
timeDown = 15;
timeControl.Resume();
}
currentMic.Remove(messageObj.id);
}
else if (messageObj.op == "pause")
{
timeControl.Suspend();
messageObj.id = timeDown.ToString();
allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(messageObj)));
return;
}
else if (messageObj.op == "start")
{
timeControl.Resume();
messageObj.id = timeDown.ToString();
allSockets.ToList().ForEach(s => s.Send(JsonConvert.SerializeObject(messageObj)));
return;
}
allSockets.ToList().ForEach(s => s.Send(message));
};
});
var input = Console.ReadLine();
while (input != "exit")
{
foreach (var socket in allSockets.ToList())
{
socket.Send(input);
}
input = Console.ReadLine();
}
}
}
internal class MsgClass
{
public string op;
public string id;
public List<string> currMic = new List<string>();
}
}
运行该程序
2.前端实现
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>抢麦器</title>
<style type="text/css">
body {
margin:0px auto;
}
#main {
width:500px;
margin:20px auto;
}
#content {
width:250px;
height:300px;
border:1px solid black;
}
#content div {
background-color:RGB(248,248,248);
color:black;
}
#content div.select {
background-color:blue;
color:white;
}
</style>
</head>
<body>
<div id="main">
<form id="sendForm">
您的名字:<input id="myname" value="用户" onchange="powerControl()"/>
<br /><br />
<a id="upmic" href="javascript:void(0);" onclick="upMic();">上麦</a>
<a id="downmic" href="javascript:void(0);" onclick="downMic();">下麦</a>
<a id="alldownmic" href="javascript:void(0);" onclick="allDownMic();" style="display:none;">全部下麦</a>
<a id="controlmic" href="javascript:void(0);" onclick="controlMic();" style="display:none;">控麦</a>
<a id="pauseAndStart" href="javascript:void(0);" onclick="pauseAndStart();" style="display:none;">暂停</a>
<a id="addtime" href="javascript:void(0);" onclick="addTime();" style="display:none;">加时</a>
剩余时间:<span id="time">0</span>
<br />
<div id="content">
</div>
</form>
<pre id="incomming"></pre>
</div>
<script src="js/common/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
var timeout;
function powerControl() {
if ($("#myname").val() == "郭孛") {
$("#alldownmic").show();
$("#controlmic").show();
$("#addtime").show();
$("#pauseAndStart").show();
}
}
function pauseAndStart() {
if ($("#myname").val() != "郭孛") {
return;
}
if ($("#content div").length == 0) {
return;
}
var json = {};
if ($("#pauseAndStart").text()=="暂停"){
json.op = "pause";
$("#pauseAndStart").text("开始");
}
else {
json.op = "start";
$("#pauseAndStart").text("暂停");
}
ws.send(JSON.stringify(json));
}
function controlMic() {
if ($("#myname").val() != "郭孛") {
return;
}
if ($("#content div.select").length == 0) {
alert("请选中用户后操作!");
}
var json = {};
json.op = "controlmic";
json.id = $("#content div.select").attr("id");
ws.send(JSON.stringify(json));
}
function upMic()
{
if ($("#" + $("#myname").val()).length > 0) {
return;
}
var json = {};
json.op = "upmic";
json.id = $("#myname").val();
ws.send(JSON.stringify(json));
}
function downMic() {
var json = {};
json.op = "downmic";
json.id = $("#myname").val();
ws.send(JSON.stringify(json));
}
function allDownMic() {
if ($("#myname").val()!="郭孛") {
return;
}
var json = {};
json.op = "alldownmic";
json.id = $("#myname").val();
ws.send(JSON.stringify(json));
}
function addTime() {
if ($("#myname").val() != "郭孛") {
return;
}
if ($("#content div").length == 0) {
return;
}
var json = {};
json.op = "addtime";
json.id = "";
ws.send(JSON.stringify(json));
}
var start = function () {
var inc = document.getElementById('incomming');
var wsImpl = window.WebSocket || window.MozWebSocket;
var form = document.getElementById('sendForm');
var input = document.getElementById('sendText');
$("#myname").val(new Date().valueOf());
inc.innerHTML += "正在连接服务器......<br/>";
window.ws = new wsImpl('ws://localhost:7181/');
ws.onmessage = function (evt) {
var data = JSON.parse(evt.data);
if (data.op == "init") {
data.currMic.forEach(c=> {
$("#content").append("<div id='" + c + "'>" + c + "</div>")
})
$("#time").text(data.id);
timeout = setInterval(function () {
var time = +$("#time").text();
$("#time").text(--time);
if (time <= 0) {
clearInterval(timeout);
}
}, 1000)
}
if (data.op == "upmic") {
if ($("#content div").length == 0) {
$("#time").text(15);
timeout = setInterval(function () {
var time = +$("#time").text();
$("#time").text(--time);
if (time <= 0) {
clearInterval(timeout);
}
},1000)
}
if ($("#" + data.id + "").length == 0) {
$("#content").append("<div id='" + data.id + "'>" + data.id + "</div>");
}
}
else if (data.op == "downmic")
{
var isfirst = false;
console.log($("#content div:first").attr("id") == data.id);
if ($("#content div:first").attr("id") == data.id) {
isfirst = true;
}
$("#" + data.id).remove();
if (isfirst && $("#content div").length > 0) {
$("#time").text(15);
}
else if ($("#content div").length == 0) {
$("#time").text("");
clearInterval(timeout);
}
}
else if (data.op == "alldownmic") {
$("#content").empty();
$("#time").empty();
clearInterval(timeout);
}
else if (data.op == "systemdownmic") {
$("#content div:first").remove();
clearInterval(timeout);
$("#pauseAndStart").text("暂停");
if ($("#content div").length > 0) {
$("#time").text(15);
timeout = setInterval(function () {
var time = +$("#time").text();
$("#time").text(--time);
if (time <= 0) {
clearInterval(timeout);
}
}, 1000)
}
else {
clearInterval(timeout);
$("#time").text("");
}
}
else if (data.op == "addtime") {
if ($("#content div").length == 0) {
return;
}
var time = +$("#time").text();
$("#time").text(time + 15);
}
else if (data.op == "controlmic") {
var selectMic = $("#content div[id='" + data.id + "']");
if (selectMic.length == 0) {
return;
}
if (selectMic.attr("id") == $("#content div:first").attr("id") && $("#content div").length > 1) {
$("#time").text(15);
}
else if (selectMic.attr("id") == $("#content div:first").attr("id") && $("#content div").length == 1) {
$("#time").text(0);
clearInterval(timeout);
}
selectMic.remove();
}
else if (data.op == "pause") {
clearInterval(timeout);
$("#time").text(data.id);
}
else if (data.op == "start") {
clearInterval(timeout);
$("#time").text(data.id);
timeout = setInterval(function () {
var time = +$("#time").text();
$("#time").text(--time);
if (time <= 0) {
clearInterval(timeout);
}
}, 1000);
}
};
ws.onopen = function () {
inc.innerHTML += '连接成功<br/>';
};
ws.onclose = function () {
inc.innerHTML += '服务器连接已断开<br/>';
}
form.addEventListener('submit', function (e) {
e.preventDefault();
var val = input.value;
ws.send(val);
input.value = "";
});
$(document).on("click","#content div", function () {
$("#content div").removeClass("select");
$(this).addClass("select");
})
}
window.onload = start;
</script>
</body>
</html>
前端页面展示 可以看到前端页面打开连接成功后,控制台会同时打印相关信息,表示该页面已成功连接服务器,我们可以多开几个页面后执行相关的功能
|