1、App.config配置文件
##App.config
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="aspnet:UseTaskFriendlySynchronizationContext" value="true" />
</appSettings>
<system.web>
<compilation debug="true" />
</system.web>
<!-- 部署服务库项目时,必须将配置文件的内容添加到
主机的 app.config 文件中。System.Configuration 不支持库的配置文件。 -->
<system.serviceModel>
<services>
<service name="Service.Service1">
<host>
<baseAddresses>
<add baseAddress = "http://localhost:8733/Design_Time_Addresses/WcfServiceLibrary1/Service1/" />
</baseAddresses>
</host>
<!-- Service Endpoints -->
<!-- 除非完全限定,否则地址相对于上面提供的基址-->
<endpoint address="net.tcp://localhost:51888/Service1/" binding="netTcpBinding" contract="Service.IService1">
<!--
部署时,应删除或替换下列标识元素,以反映
用来运行所部署服务的标识。删除之后,WCF 将
自动推断相应标识。
-->
<identity>
<dns value="localhost"/>
</identity>
</endpoint>
<!-- Metadata Endpoints -->
<!-- 元数据交换终结点供相应的服务用于向客户端做自我介绍。 -->
<!-- 此终结点不使用安全绑定,应在部署前确保其安全或将其删除-->
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange"/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior>
<!-- 为避免泄漏元数据信息,
请在部署前将以下值设置为 false -->
<serviceMetadata httpGetEnabled="True" httpsGetEnabled="True"/>
<!-- 要接收故障异常详细信息以进行调试,
请将以下值设置为 true。在部署前设置为 false
以避免泄漏异常信息 -->
<serviceDebug includeExceptionDetailInFaults="False" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
2、IService1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace Service
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
[ServiceContract(Namespace = "IService",
CallbackContract = typeof(IService1Callback))]
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
public interface IService1
{
// TODO: 在此添加您的服务操作
//[OperationContract(IsOneWay = true)]
//void InitRooms();
[OperationContract(IsOneWay = true)]
void Login(string userName); //登录系统
[OperationContract(IsOneWay = true)]
void Logout(string userName); //登出系统
[OperationContract(IsOneWay = true)]
void Talk(string userName, string message); //大厅聊天
[OperationContract(IsOneWay = true)]
void InRoom(string username, string roomname); //进入游戏房间
[OperationContract(IsOneWay = true)]
void Room_Talk(string userName, string message); //房间内聊天
[OperationContract(IsOneWay = true)]
void sendink(string username, string ink); //传送笔迹
[OperationContract(IsOneWay = true)]
void Guess_talk(string username, string message); //猜测框消息
[OperationContract(IsOneWay = true)]
void Gusee_win(string username); //猜测正确
[OperationContract(IsOneWay = true)]
void change_hua(string username); //改变画题人
[OperationContract(IsOneWay = true)]
void Refersh_Timu(string username); //刷新题目
[OperationContract(IsOneWay = true)]
void RoomOut(string username); //用户退出房间
}
public interface IService1Callback
{
[OperationContract(IsOneWay = true)]
void ShowLogin(string loginUserName, int[] roomcount); //显示新用户登录游戏,进入大厅
[OperationContract(IsOneWay = true)]
void ShowLogout(string userName); //显示用户退出游戏
[OperationContract(IsOneWay = true)]
void ShowTalk(string userName, string message); //在大厅发消息显示消息内容
[OperationContract(IsOneWay = true)]
void InitRoomUsersInfo(string RoomUsersInfo, string ink, bool hua_or_cai, string timu); //初始化房间玩家列表
[OperationContract(IsOneWay = true)]
void ShowInRoom(string username); //显示用户进入房间
[OperationContract(IsOneWay = true)]
void ShowOutRoom(string userName); //显示用户退出房间
[OperationContract(IsOneWay = true)]
void Showlabel(string labelname, int roomusercount); //大厅界面显示四个房间的人数
[OperationContract(IsOneWay = true)]
void Show_Room_Talk(string userName, string message); //显示在房间里聊天的消息
[OperationContract(IsOneWay = true)]
void Show_Room_Talk_error(string message); //显示在房间里聊天的消息
[OperationContract(IsOneWay = true)]
void Show_Guess_Talk(string userName, string message, string daan); //显示猜测聊天框中的聊天消息
[OperationContract(IsOneWay = true)]
void Showink(string ink); //显示墨迹信息
[OperationContract(IsOneWay = true)]
void Show_Guess_win(string username); //显示用户猜中
[OperationContract(IsOneWay = true)]
void Show_Refersh_Timu(string username, string Timu); //刷新题目后,在各个玩家界面显示
[OperationContract(IsOneWay = true)]
void Show_Cannot_login();//提示用户不能登录
[OperationContract(IsOneWay = true)]
void InitNewchutiren(string timu);//初始化新的出题人界面
[OperationContract(IsOneWay = true)]
void change_hua_or_cai(bool hua, string username);//改变画题人和猜题人
}
}
3、游戏房间:Room.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Service
{
class Room
{
public string RoomName { get; set; } //游戏房间名
public readonly IService1Callback callback;
public List<Users> game_user { get; set; } //房间玩家列表
public string Timu; //房间的游戏题目
public string ink; //房间的墨迹信息
public Room(string RoomName, IService1Callback callback)//构造函数
{
this.RoomName = RoomName;
this.callback = callback;
this.game_user = new List<Users>();
string str_1 = System.AppDomain.CurrentDomain.BaseDirectory;
Timu = refer_timu(str_1 + "\\tiku.txt");
ink = "";
}
public string refer_timu(string path)//刷新题库
{
string[] line = File.ReadAllLines(path);
Random ro = new Random();
int co = ro.Next(0, line.Length);
Timu = line[co];
return Timu;
}
}
}
4、房间列表类:RoomInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel;
using System.Text;
using System.Threading.Tasks;
namespace Service
{
class RoomInfo
{
public static List<Room> Rooms { get; set; } //系统房间列表
static RoomInfo()
{
Rooms = new List<Room>();
for (int i = 1; i <= 4; i++)//初始化四个房间
{
string roomname = "room" + i.ToString();
OperationContext context1 = OperationContext.Current;
IService1Callback callback1 = context1.GetCallbackChannel<IService1Callback>();
Room room = new Room(roomname, callback1);
Rooms.Add(room);
}
} //构造函数
public static Room GetRoom(string roomname)
{
Room room = null;
foreach (var v in Rooms)
{
if (v.RoomName == roomname)
{
room = v;
break;
}
}
return room;
}//获取对应的房间
}
}
5、Service1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace Service
{
// 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的类名“Service1”。
public class Service1 : IService1
{
public void Login(string userName) //登录系统
{
//在线用户列表中加入该用户
OperationContext context = OperationContext.Current;
IService1Callback callback = context.GetCallbackChannel<IService1Callback>();
Users newUser = new Users(userName, callback);
//判断是否存在该用户
foreach (var v in UserInfo.Users)
{
if (v.UserName == userName)
{
newUser.callback.Show_Cannot_login();
return;
}
}
//如果不存在将该用户加入房间列表
UserInfo.Users.Add(newUser);
//获得房间人数,显示用户登录,并初始化该用户界面
int[] a = new int[5];
for (int i = 0; i < 4; i++)
{
a[i] = RoomInfo.Rooms[i].game_user.Count();
}
foreach (var user in UserInfo.Users)
{
user.callback.ShowLogin(userName, a);
}
}
public void Logout(string userName) //登出系统
{
//在线用户列表中移除该用户
Users logoutUser = UserInfo.GetUser(userName);
//如果该用户在房间中,则从该房间玩家列表中移除该用户
if (logoutUser.inRoom)
{
RoomOut(userName);
}
//从在线玩家列表移除该用户
UserInfo.Users.Remove(logoutUser);
logoutUser = null;
//展示用户退出游戏
foreach (var user in UserInfo.Users)
{
user.callback.ShowLogout(userName);
}
}
public void Talk(string userName, string message) //大厅聊天
{
//向所有用户显示聊天消息
foreach (var v in UserInfo.Users)
{
v.callback.ShowTalk(userName, message);
}
}
public bool Filter(string timu, string message) //画图人不能说出与答案有关的话
{
return message.Contains(timu);
}
public void Room_Talk(string userName, string message) //房间内聊天
{
//获得相应的用户和房间
Users user = UserInfo.GetUser(userName);
Room room = RoomInfo.GetRoom(user.RoomName);
//过滤
if (Filter(room.Timu, message) && user.hua_or_cai)
{
user.callback.Show_Room_Talk_error("可能包含答案信息,发送失败。");
return;
}
//向房间内所有用户显示消息
foreach (var v in room.game_user)
{
v.callback.Show_Room_Talk(userName, message);
}
}
public void Guess_talk(string username, string message) //猜测框消息
{
//同上
Users user = UserInfo.GetUser(username);
Room room = RoomInfo.GetRoom(user.RoomName);
foreach (var v in room.game_user)
{
v.callback.Show_Guess_Talk(username, message, room.Timu);
}
}
public void InRoom(string username, string roomname) //进入游戏房间
{
//获取相应的用户和房间
Users inroomuser = UserInfo.GetUser(username);
Room room = RoomInfo.GetRoom(roomname);
//如果是房间的第一个人,则这个人画画,以后进来的人猜
if (room.game_user.Count == 0)
inroomuser.hua_or_cai = true;
else
inroomuser.hua_or_cai = false;
inroomuser.inRoom = true;
inroomuser.RoomName = roomname;
//初始化新进来玩家的界面
//初始化新进来的玩家的玩家列表界面、题目和画板墨迹
string str = "";
for (int i = 0; i < room.game_user.Count; i++)
{
str += room.game_user[i].UserName + "、";
}
if (room.game_user.Count == 0)
inroomuser.callback.InitRoomUsersInfo(str.TrimEnd('、'), null, inroomuser.hua_or_cai, room.Timu);
else
inroomuser.callback.InitRoomUsersInfo(str.TrimEnd('、'), room.ink, inroomuser.hua_or_cai, room.Timu);
//该房间的玩家列表加入该玩家
room.game_user.Add(inroomuser);
//获得用户进入房间对应的人数标签名字
string labelname = roomname + "_user_count";
//展示用户进入游戏房间
foreach (var user in room.game_user)
{
user.callback.ShowInRoom(username);
}
//更改所有用户大厅的房间人数标签
foreach (var user in UserInfo.Users)
{
user.callback.Showlabel(labelname, room.game_user.Count());
}
}
public void sendink(string username, string ink) //传送笔迹
{
Users user = UserInfo.GetUser(username);
Room room = RoomInfo.GetRoom(user.RoomName);
//设置房间的墨迹信息,同时向所有玩家同步
room.ink = ink;
foreach (var v in room.game_user)
{
v.callback.Showink(room.ink);
}
}
public void Gusee_win(string username) //猜测正确
{
Users user = UserInfo.GetUser(username);
Room room = RoomInfo.GetRoom(user.RoomName);
//房间墨迹清空。向所有用户展示某用户猜对
room.ink = null;
foreach (var v in room.game_user)
{
v.callback.Show_Guess_win(username);
}
//猜对的人成为画题人,其余人猜题
change_hua(username);
}
public void Refersh_Timu(string username) //刷新题目
{
Users user = UserInfo.GetUser(username);
Room room = RoomInfo.GetRoom(user.RoomName);
//获得题库地址刷新题目,并清空墨迹
string str_1 = System.AppDomain.CurrentDomain.BaseDirectory;
room.Timu = room.refer_timu(str_1 + "\\tiku.txt");
room.ink = "";
foreach (var v in room.game_user)
{
v.callback.Show_Refersh_Timu(username, room.Timu);
v.callback.Showink(room.ink);
}
}
public void RoomOut(string username)
{
Users logoutUser = UserInfo.GetUser(username);
Room room = RoomInfo.GetRoom(logoutUser.RoomName);
logoutUser.inRoom = false;
logoutUser.RoomName = "";
//如果玩家不是画题人,正常退出。否则在猜题人中选择一个作为新的画题人。
if (!logoutUser.hua_or_cai)
{
logoutUser.callback.ShowOutRoom(username);
foreach (var user in room.game_user)
{
user.callback.ShowOutRoom(username);
}
room.game_user.Remove(logoutUser);
}
else
{
logoutUser.hua_or_cai = false;
foreach (var item in room.game_user)
{
if (item.UserName != logoutUser.UserName)
{
item.hua_or_cai = true;
item.callback.InitNewchutiren(room.Timu);
break;
}
}
room.ink = "";
foreach (var v in room.game_user)
v.callback.Showink(room.ink);
foreach (var user in room.game_user)
{
user.callback.ShowOutRoom(username);
}
room.game_user.Remove(logoutUser);
}
//更新大厅的房间信息
foreach (var v in UserInfo.Users)
{
v.callback.Showlabel(room.RoomName + "_user_count", room.game_user.Count());
}
//如果房间剩余人数为0,清空墨迹信息
if (room.game_user.Count() == 0)
room.ink = "";
} //用户退出房间
public void change_hua(string username) //改变画题人
{
Users old_User = null;
foreach (var item in UserInfo.Users)
{
if (item.hua_or_cai)
{
old_User = item;
break;
}
}
Users new_User = UserInfo.GetUser(username);
Room room = RoomInfo.GetRoom(new_User.RoomName);
old_User.hua_or_cai = false;
new_User.hua_or_cai = true;
old_User.callback.change_hua_or_cai(false, new_User.UserName);
new_User.callback.change_hua_or_cai(true, new_User.UserName);
}
}
}
6、用户列表:UserInfo.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Service
{
class UserInfo
{
public static List<Users> Users { get; set; } //在线用户列表
static UserInfo()
{
Users = new List<Users>();
}//构造函数
public static Users GetUser(string userName)
{
Users user = null;
foreach (var v in Users)
{
if (v.UserName == userName)
{
user = v;
break;
}
}
return user;
} //获得用户
}
}
7、用户类:Users.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Service
{
class Users
{
public string UserName { get; set; } //用户名
public readonly IService1Callback callback;
public bool hua_or_cai; //画题人或者出题人
public bool inRoom; //用户是不是在房间内
public string RoomName; //用户如果在房间内,则对应的额房间名
public Users(string userName, IService1Callback callback) //构造函数
{
this.UserName = userName;
this.callback = callback;
hua_or_cai = false;
inRoom = false;
RoomName = "";
}
}
}