Java+Unity實現簡單通信
原本准備實現
后端:java+spring+netty+mysql
但由於很久沒有使用sql,便只使用了java+spring+netty的解決方案。
內容實現為簡單的查詢和登錄功能。
后端實現
使用了spring webflux框架
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
Bean:userbean儲存信息
public class UserBean {
private String name;
private String passWord;
public UserBean(String name, String passWord) {
super();
this.name = name;
this.passWord = passWord;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
@Override
public String toString() {
return "UserBean [name=" + name + ", passWord=" + passWord + "]";
}
}
這里沒有使用server層和dao層,只寫了control層相應請求。
@RestController
public class GameService {
@CrossOrigin
@GetMapping("/hello")
public String hello() {
return "hello";
}
//登錄
@PostMapping("/login")
public boolean login(UserBean userBean) {
System.out.println(userBean);
//登錄信息必須為賬號123,密碼123456,才認證成功
if(userBean.getName().equals("123") && userBean.getPassWord().equals("123456")) {
return true;
}else {
return false;
}
}
//注冊
@PutMapping("/register")
public boolean register(@RequestBody UserBean userBean) {
System.out.println(userBean);
return true;
}
//獲取用戶列表
@GetMapping("/user")
@ResponseBody
public ArrayList<UserBean> getUsers() {
UserBean user1 = new UserBean("123465", "aaaa");
UserBean user2 = new UserBean("zzzz", "aaaa");
ArrayList<UserBean> list = new ArrayList<UserBean>();
list.add(user1);
list.add(user2);
return list;
}
}
webflux的過濾器,可以實現一些過濾功能,這里僅測試用
//@Component
@Configuration
public class TestServletFilter implements WebFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
// TODO Auto-generated method stub
System.out.println("新的請求");
exchange.getSession().doOnNext(t -> {
System.out.println(t.getId());
});
System.out.println(exchange.getRequest().getPath());
System.out.println(exchange.getResponse().getStatusCode());
System.out.println(exchange.getSession().subscribe(t -> {
System.out.println(t.getId());
t.save();
}));
return chain.filter(exchange);
}
}
unity
搭建ui
登錄

注冊

列表

制作相應的ui控制腳本,這里只展示UnityWebRequest的使用,由web管理組件控制。
public class WebSocketManager : MonoBehaviour
{
//UI管理器引用
public UIManager uIManager;
//web管理器唯一引用,以便其他對象引用
public static WebSocketManager socketManager;
//host
public string host = "http://127.0.0.1";
void Start()
{
//單例
if(socketManager!= null)
{
Destroy(gameObject);
}
else
{
socketManager = this;
}
}
//登錄
public void login(string name, string pw)
{
StartCoroutine(_login(name, pw));
}
//登錄的協程
public IEnumerator _login(string name,string pw)
{
string url = host + "/login";
//創建表單數據,發送請求
List<IMultipartFormSection> fromData = new List<IMultipartFormSection>();
fromData.Add(new MultipartFormDataSection("name", name));
fromData.Add(new MultipartFormDataSection("passWord", pw));
UnityWebRequest request =UnityWebRequest.Post(url,fromData);
yield return request.SendWebRequest();
if(request.result != UnityWebRequest.Result.Success)
{
Debug.LogWarning("請求失敗:"+request.error);
}
else
{
Debug.Log(request.downloadHandler.text);
bool isLogin = bool.Parse(request.downloadHandler.text);
//請求為ture后跳轉至主頁面
if (isLogin)
{
uIManager.OpenMain();
}
}
}
//獲得多個用戶
public void getuser()
{
StartCoroutine(_getUser());
}
//獲得多個用戶的協程
IEnumerator _getUser()
{
string url = host+"/user";
UnityWebRequest request = UnityWebRequest.Get(url);
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
Debug.LogWarning("請求失敗:" + request.error);
}
else
{
Debug.Log(request.downloadHandler.text);
//使用jsonNet將list的json數據轉換為list對象
List<UserBean> users = JsonConvert.DeserializeObject<List<UserBean>>(request.downloadHandler.text);
//unity自帶的json轉換器不能轉換list對象
//List<UserBean> users = JsonUtility.FromJson<List<UserBean>>(request.downloadHandler.text);
//主頁面數據更新
uIManager.main.updataUserData(users);
}
}
//注冊
public void regist(string name, string pw)
{
StartCoroutine(_register(name, pw));
}
//注冊的協程
IEnumerator _register(string name,string pw)
{
string url =host+ "/register";
UserBean user = new UserBean();
user.name = name;
user.passWord = pw;
string data = JsonUtility.ToJson(user);
Debug.Log("發送信息:" + data);
//發送put請求,並將改寫contentType
UnityWebRequest request = UnityWebRequest.Put(url, data);
request.uploadHandler.contentType = "application/json";
yield return request.SendWebRequest();
if (request.result != UnityWebRequest.Result.Success)
{
Debug.LogWarning("請求失敗:" + request.error);
}
else
{
Debug.Log(request.downloadHandler.text);
bool isRigster = bool.Parse(request.downloadHandler.text);
//注冊成功,跳轉至登錄頁面
if (isRigster)
{
uIManager.OpenLogin();
}
}
}
}
演示效果:

整體上,沒有什么難度,只是在netty中沒有session,花了很大的時間才發現為什么sessionID一直在變,對於netty需要自己去實現sessionID的細節來保持會話。
