internal void BroadcastInterChat(MessageSession session, InterChatMsg msg) { _interChatLock.DoRead(() => { var userName = "******"; if (_interChatUserMap.ContainsKey(session)) userName = _interChatUserMap[session]; BroadcastChatMsgWithNoLock(userName, msg.Message); }); }
public void Execute(int serverIndex, string userName) { if (string.IsNullOrWhiteSpace(userName)) { throw new InvalidOperationException("Invalid username"); } if (!File.Exists(ClientExecutablePath)) { throw new InvalidOperationException("Cannot find a client binary.\nPlease restart this launcher."); } var server = _serversLock.DoRead( () => serverIndex >= 0 && serverIndex < _serverMsgs.Count ? _serverMsgs[serverIndex] : null); if (server == null) { throw new InvalidOperationException("No server selected."); } using (var clientProcess = new Process()) { clientProcess.StartInfo.FileName = ClientExecutablePath; clientProcess.StartInfo.Arguments = string.Format(@"--username ""{0}"" --server ""{1}""", userName, server.Host); clientProcess.StartInfo.WorkingDirectory = ClientPath; clientProcess.StartInfo.WindowStyle = ProcessWindowStyle.Normal; clientProcess.Start(); } }
internal void RequestServer(MessageSession session, RequestServerMsg msg) { _serverMapLock.DoRead(() => { var response = new ServersMsg(); response.ServerList.AddRange(_serverMap.Values); session.Send(response); Logger.Write("Response To: {0} -> {1}", session.ClientSocket.RemoteEndPoint, _serverMap.Count); }); }
public bool ExecuteHandler(int typeId, Action <THandler> action) { return(_lock.DoRead(() => { if (!_handlerMap.ContainsKey(typeId)) { return false; } _handlerMap[typeId].ForEach(action); return true; })); }
internal void LoginInterChat(MessageSession session, InterChatLoginMsg msg) { _interChatLock.DoWrite(() => { // 중복 로그인 방지 if (_interChatUserMap.ContainsValue(msg.Name)) { Logger.Write("Connected: Duplicate Login [{0}]", msg.Name); session.Send(new InterChatCommandMsg {TypeCode = (int) InterChatCommandType.CheckUserName, Content = "false"}); return; } session.Send(new InterChatCommandMsg { TypeCode = (int)InterChatCommandType.CheckUserName, Content = "true" }); Logger.Write("Connected: InterChat [{0}]", msg.Name); // 먼저 목록을 보내주고, session.Send(new InterChatCommandMsg { TypeCode = (int)InterChatCommandType.InformLoggedUsers, Content = SerializeUserListWithNoLock() }); // 예전 채팅 내역이 있으면 보내준 뒤, // ReSharper disable ImplicitlyCapturedClosure _interChatMessageLock.DoRead(() => { var skipCount = Math.Max(0, _lastMessages.Count - LastClientMessageCount); foreach (var lastMessage in _lastMessages.Skip(skipCount).Take(LastClientMessageCount)) session.Send(lastMessage); }); // ReSharper restore ImplicitlyCapturedClosure // 맵에 자기 자신을 추가한 뒤, 자신에 대한 정보도 같이 처리한다. _interChatUserMap.Add(session, msg.Name); BroadcastChatMsgWithNoLock("system", msg.Name + "께서 접속하였습니다."); BroadcastCommandMsgWithNoLock(InterChatCommandType.InformLoggedUser, FindOrCreateUserWithLock(msg.Name).ToString()); }); }
public ChainedHeader FindMaxTotalWork() { return(totalWorkLock.DoRead(() => { var maxTotalWork = BigInteger.Zero; var candidateHeaders = new List <ChainedHeader>(); var finished = false; foreach (var totalWork in chainedHeadersByTotalWork.Keys) { var headersAtTotalWork = chainedHeadersByTotalWork[totalWork]; foreach (var chainedHeader in headersAtTotalWork) { // check if this block is valid if (!invalidBlocks.Contains(chainedHeader.Hash)) { // initialize max total work, if it isn't yet if (maxTotalWork == BigInteger.Zero) { maxTotalWork = chainedHeader.TotalWork; } // add this header as a candidate if it ties the max total work if (chainedHeader.TotalWork >= maxTotalWork) { candidateHeaders.Add(chainedHeader); } else { finished = true; break; } } } if (finished) { break; } } // take the earliest header seen with the max total work candidateHeaders.Sort((left, right) => left.DateSeen.CompareTo(right.DateSeen)); return candidateHeaders.FirstOrDefault(); })); }
public UnconfirmedTxes ToImmutable() { return(commitLock.DoRead(() => new UnconfirmedTxes(chain.Value, storageManager))); }
private void BlockchainWorker() { try { var winningBlockchainLocal = this.WinningBlockchain; if (winningBlockchainLocal.IsDefault) { return; } var winningBlockLocal = this.WinningBlock; var currentBlockchainLocal = this.CurrentBlockchain; // check if the winning blockchain has changed if (currentBlockchainLocal == null || (currentBlockchainLocal.RootBlockHash != winningBlockLocal.BlockHash)) { var lastCurrentBlockchainWriteLocal = this.lastCurrentBlockchainWrite; using (var cancelToken = new CancellationTokenSource()) { //TODO cleanup this design List <MissingDataException> missingData; // try to advance the blockchain with the new winning block var newBlockchain = Calculator.CalculateBlockchainFromExisting(currentBlockchainLocal, winningBlockLocal, out missingData, cancelToken.Token, progressBlockchain => { // check that nothing else has changed the current blockchain currentBlockchainLock.DoRead(() => { if (lastCurrentBlockchainWriteLocal != this.lastCurrentBlockchainWrite) { cancelToken.Cancel(); return; } }); // update the current blockchain lastCurrentBlockchainWriteLocal = UpdateCurrentBlockchain(progressBlockchain); // let the blockchain writer know there is new work this.writeBlockchainWorker.NotifyWork(); }); // collect after processing GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced, blocking: true); // handle any missing data that prevented further processing foreach (var e in missingData) { HandleMissingData(e); } } // whenever the chain is successfully advanced, keep looking for more //this.blockchainWorker.NotifyWork(); // kick off a blockchain revalidate after update this.validateCurrentChainWorker.NotifyWork(); } } catch (ValidationException e) { //TODO // an invalid blockchain with winning work will just keep trying over and over again until this is implemented } catch (MissingDataException e) { HandleMissingData(e); } catch (AggregateException e) { foreach (var missingDataException in e.InnerExceptions.OfType <MissingDataException>()) { HandleMissingData(missingDataException); } //TODO //var validationException = e.InnerExceptions.FirstOrDefault(x => x is ValidationException); //if (validationException != null) // throw validationException; //TODO //throw; } }
public int this[string name] { get { return(_lock.DoRead(() => _cacheMap[name])); } }
public MessageSession this[int sessionId] { get { return(_lock.DoRead(() => _sessionMap[sessionId])); } }
private InterChatUser FindUserFromSessionWithLock(MessageSession session) { var userName = FindUserNameFromSessionWithLock(session); return _userMapLock.DoRead(() => _userMap.ContainsKey(userName) ? _userMap[userName] : null); }
private static void SendPingPacket<T>(ReaderWriterLockSlim locker, Dictionary<MessageSession, T> sessionMap) { foreach (var session in locker.DoRead(() => sessionMap.Keys.ToArray())) session.Send(new AlivePingMsg()); }