我正在开展视频直播项目,以探索HTML5视频和二进制流的深度。只需有人可以通过JavaScript UserMedia API使用他们的网络摄像头,其他人可以连接到他们的房间并观看它们。它建立在React和NodeJS之上。
我计划以同形方式构建这个应用程序,以再次探索该领域新元素的深度。
当我意识到我无法访问 CLIENT-SIDE JavaScript导航器对象时,我很快就踢了一脚,因为应用程序未在浏览器上下文中执行。 DOH。
我的解决方案是强制流式用户下载要在浏览器上下文中执行的单个React组件文件。然而,这似乎并不太优雅,因为这意味着我必须非常严重地打破同构模式,并且必须为流功能引入面向公众的API。这也意味着React被分为2个实例,据我所知,它们之间无法相互通信(但我相信我可能会认为这是假的)
TLDR; 有人可以指导我从nodeJS同构React应用程序访问客户端导航器API的可能优雅的解决方案吗?
答案 0 :(得分:0)
您无法在NodeJS中使用navigator API,因为它只在浏览器中实现。如果您正在尝试找到一个好的解决方案以避免服务器上的执行错误,那么您可以检查是否window
和使用导航器componentDidMount()
是否存在。此外,您可以将带有导航器部分的代码放在React组件中的using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.IO;
public class DistrictSaveData : KeepAwake {
private string saveDirectoryPath = string.Concat(
System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments),
"\\My Games\\District\\Districts");
private string saveFilePath = string.Concat(
System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments),
"\\My Games\\District\\Districts\\District-x.dat");
private StreamReader saveFileReader;
public void SaveAll() {
foreach (GameObject gO in GameObject.FindGameObjectsWithTag("District")) {
District district = gO.GetComponent<District>();
saveFilePath = string.Concat(
System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments),
"\\My Games\\District\\Districts\\District-", district.id , ".dat");
if (!Directory.Exists(saveDirectoryPath)) {
Directory.CreateDirectory(saveDirectoryPath);
}
try {
File.Delete(saveFilePath);
} catch {}
File.Create(saveFilePath);
File.WriteAllText(saveFilePath, district.SendSaveData());
}
}
public void LoadAll() {
foreach (GameObject gO in GameObject.FindGameObjectsWithTag("District")) {
District district = gO.GetComponent<District>();
saveFilePath = string.Concat(
System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments),
"\\My Games\\District\\Districts\\District-", district.id , ".dat");
if(File.Exists(saveFilePath)) {
OpenFileForReading();
district.isHQ = bool.Parse(saveFileReader.ReadLine());
district.controllingFaction = StringToFaction(saveFileReader.ReadLine());
district.agricultureSpecialisation = StringToAgricultureSpecialisation(saveFileReader.ReadLine());
district.technologySpecialisation = StringToTechnologySpecialisation(saveFileReader.ReadLine());
district.militarySpecialisation = StringToMilitarySpecialisation(saveFileReader.ReadLine());
CloseFileAfterReading();
} else
break;
}
}
/// <summary>
/// Opens the save file for reading.
/// </summary>
private void OpenFileForReading() {
saveFileReader = File.OpenText(saveFilePath);
}
/// <summary>
/// Closes the save file after reading.
/// </summary>
private void CloseFileAfterReading() {
saveFileReader.Close();
}
private Faction StringToFaction(string stringToConvert) {
switch (stringToConvert) {
case "TheCrimsonLegion":
return Faction.TheCrimsonLegion;
case "TheVanguardsOfChaos":
return Faction.TheVanguardsOfChaos;
case "TheEmeraldFoxes":
return Faction.TheEmeraldFoxes;
case "TheSyndicate":
return Faction.TheSyndicate;
case "TheKeepersOfTheTome":
return Faction.TheKeepersOfTheTome;
case "TheArchitectsOfThought":
return Faction.TheArchitectsOfThought;
default:
return Faction.None;
}
}
private AgricultureSpecialisation StringToAgricultureSpecialisation(string stringToConvert) {
switch (stringToConvert) {
case "Farm":
return AgricultureSpecialisation.Farm;
case "Plantation":
return AgricultureSpecialisation.Plantation;
case "Biodome":
return AgricultureSpecialisation.Biodome;
default:
return AgricultureSpecialisation.None;
}
}
private TechnologySpecialisation StringToTechnologySpecialisation(string stringToConvert) {
switch (stringToConvert) {
case "Laboratory":
return TechnologySpecialisation.Laboratory;
case "University":
return TechnologySpecialisation.University;
case "GreatTechnologicalInstitution":
return TechnologySpecialisation.GreatTechnologicalInstitution;
default:
return TechnologySpecialisation.None;
}
}
private MilitarySpecialisation StringToMilitarySpecialisation(string stringToConvert) {
switch (stringToConvert) {
case "Outpost":
return MilitarySpecialisation.Outpost;
case "Barracks":
return MilitarySpecialisation.Barracks;
case "Fortress":
return MilitarySpecialisation.Fortress;
default:
return MilitarySpecialisation.None;
}
}
}
函数中(如果它是与组件相关的代码) - 它只在客户端执行。